搜索
高级检索
高级搜索
书       名 :
著       者 :
出  版  社 :
I  S  B  N:
文献来源:
出版时间 :
Netty进阶之路:跟着案例学Netty
0.00    
图书来源: 浙江图书馆(由图书馆配书)
  • 配送范围:
    全国(除港澳台地区)
  • ISBN:
    9787121352621
  • 作      者:
    李林锋著
  • 出 版 社 :
    电子工业出版社
  • 出版日期:
    2019
收藏
编辑推荐

Netty是Java高性能网络编程的明星框架

在阿里等互联网公司Netty是程序员必须掌握的基础组件

现有Netty图书多是讲解其实现及原理的,缺少对实际应用的指导

在实际使用中遇到Netty故障,需要花大量实践摸索、试验解决

本书作者经过多年的积累,将遇到的问题进行分门别类的讲解

连接池资源泄漏、服务端意外退出、高并发性能波动及IoT海量连接等

除了描述问题的前因后果,还讲解了问题定位的各种思路和方法

以及对于Netty关键技术的剖许,再加上作者酣畅淋漓的文风

可以让你快速领悟到Netty专家花大量时间积累的经验

对于提高编程水平及分析解决问题的能力大有帮助

展开
作者简介

李林锋

10年Java NIO通信框架、平台中间件架构设计和开发经验。

目前在华为终端应用市场负责业务微服务化、云化、全球化等相关设计和开发工作。

《Netty木又威指南》和《分布式服务框架原理与实践》作者。


展开
内容介绍

Netty将Java NIO接口封装,提供了全异步编程方式,是各大Java项目的网络应用开发必备神器。《Netty进阶之路:跟着案例学Netty》作者是国内Netty技术的先行者和布道者,本书是他继《Netty木又威指南》之后的又一力作。

在《Netty进阶之路:跟着案例学Netty》中,作者将在过去几年实践中遇到的问题,以及Netty学习者咨询的相关问题,进行了归纳和总结,以问题案例做牵引,通过对案例进行剖析,讲解问题背后的原理,并结合Netty源码分析,让读者能够真正掌握Netty,在实际工作中少犯错。

《Netty进阶之路:跟着案例学Netty》中的案例涵盖了Netty的启动和停止、内存、并发多线程、性能、可靠性、安全等方面,囊括了Netty绝大多数常用的功能及容易让人犯错的地方。在案例的分析过程中,还穿插讲解了Netty的问题定位思路、方法、技巧,以及解决问题使用的相关工具,对读者在实际工作中用好Netty具有很大的帮助和启发作用。

《Netty进阶之路:跟着案例学Netty》适合架构师、设计师、开发工程师、测试工程师,以及对Java NIO框架、Netty感兴趣的其他相关人士阅读。

展开
精彩书评

相比传统的阻塞式编程方式,要驾驭Netty的异步编程方式是有一定难度的。Netty为了避免JVM GC和提高性能会直接对内存进行处理,使用者需要对Netty的内存使用有深入了解。本书通过一个个Netty实际使用案例为开发者展示了大量Netty技术的细节,读者可以快速领悟到Netty专家花大量时间积累的经验。

——华为开源能力中心技术专家、红帽软件前首席软件工程师  姜宁

 

本书带你领略使用Netty过程中的各种“坑”,包括客户端连接池资源泄漏、服务端意外退出、高并发性能波动及IoT海量连接性能问题等。书中除了描述问题的前因后果,还讲解了问题定位的各种思路,“授人以鱼不如授人以渔”,定位问题就像破案,“从蛛丝马迹中寻找线索,从千军万马中取上将首级”,从而快速解决问题。

——华为消费者云服务微服务首席架构师 王世军

 

Netty已经是网络编程的明星框架了,在阿里Netty也是程序员必须掌握的基础组件。李林锋在本书中总结了工作中遇到的各种问题,通过对问题的深入分析,挖掘Netty框架的工作原理。相信这又是一本非常值得大家深入学习的程序员进阶教材。

——阿里资深技术专家 天民

 

从2014年开始,李林锋就断断续续地在InfoQ网站上发布了一系列Netty文章,涵盖了Netty技术的方方面面,这些文章深受读者喜欢。这一次他的新书以实践为切入点,从场景出发,为用户深刻地剖析Netty技术的关键点,再加上他酣畅淋漓的文风,看得我甚是陶醉。

——极客邦科技/极客时间总编辑 郭蕾

  

随着云计算、容器、边缘计算、IoT等技术的发展,越来越多的高性能应用构建在轻量级的Netty之上,如API服务网关、IoT设备接入平台、轻量级边缘计算引擎等。在构建过程中我们一定会遇到一些“疑难杂症”,而本书提供了相应的“解药”,可达到“书到病除”之效。

——《亿级流量网站架构核心技术》作者 张开涛

 

Netty是一款经典的Java开源通信框架,是Java开发工程师必备技能之一。李林锋在高性能通信框架及微服务领域有很深的造诣,本书总结了Netty的各种案例和调优经验,干货满满,不容错过!

——贝壳金服 2B2C CTO、微信公众号“IT民工闲话”作者 史海峰

 

Netty好比Java网络世界中的高铁,坐上它,高性能、高并发网络应用开发似乎变得轻而易举,但李林锋通过这本书告诉我们事实并非如此简单,他用一个个活生生的案例讲述了Netty的“坑”在哪里,“门”又在哪里。

——阿里云弹性计算架构师 蔡俊杰

 

继《Netty木又威指南》之后,非常高兴李林锋又推出了本书,通过一系列Netty应用故障和案例分析,深入Netty内部实现细节,不仅有助于更好地使用Netty,而且可借此了解高并发通信场景下的应用特性,以及Netty的设计思路。技术进阶之路尽在细节与实践。

——《大型网站技术架构:核心原理与案例分析》作者 李智慧

 

李林锋是国内Netty技术的先行者和布道者,他写的《Netty木又威指南》让开发者认识到了Netty的威力,但是在实际使用Netty时还是会遇到各种问题。本书详细讲解了他在使用Netty时遇到的各种问题及分析解决问题的思路和方法,是来自一线的宝贵经验总结,对于提高编程水平及分析解决问题的能力大有帮助。

——东软集团架构师、InfoQ社区编辑、技术图书译者 张卫滨

 

认识李林锋已久,一直“神往”,他在微服务架构领域有很深的造诣,经历了从框架层、平台层到业务层的完整过程。本书侧重于程序实战,对Netty开发过程中的难点进行了详述,辅以各种实际业务问题,同时对目前主流的RPC框架进行了剖析,对网络通信开发及RPC选型都有非常好的借鉴意义。

——东方证券首席架构师 樊建

展开
精彩书摘

3.2.2 Netty内存池工作原理分析

Netty的内存池整体上参照jemalloc实现,主要数据结构如下。

(1)PooledArena:代表内存中一大块连续的区域,PoolArena由多个Chunk组成,每个Chunk由多个Page组成。为了提升并发性能,内存池中包含一组PooledArena。

(2)PoolChunk:用来组织和管理多个Page的内存分配和释放,默认为16MB。

(3)PoolSubpage:对于小于一个Page的内存,Netty在Page中完成分配。每个Page会被切分成大小相等的多个存储块,存储块的大小由第一次申请的内存块大小决定。假如一个Page是8字节,如果第一次申请的块大小是4字节,那么这个Page就包含两个存储块;如果第一次申请的块大小是8字节,那么这个Page就被分成一个存储块。一个Page只能用于分配与第一次申请时大小相同的内存,比如,一个4字节的Page,如果第一次分配了1字节的内存,那么后面这个Page只能继续分配1字节的内存,如果有一个申请2字节内存的请求,就需要在新的Page中进行分配。

内存池的内存分配从PooledArena开始,一个PooledArena包含多个Chunk(PoolChunk),Chunk具体负责内存的分配和回收。每个Chunk包含多个Page(PoolSubpage),每个Page由大小相等的块(Region)组成,每个Page块大小由第一次从Page申请的内存大小决定,某个Page中的块大小是相等的。PoolChunk默认为16MB,包含2048个Page,每个Page为8KB。

内存分配策略:通过PooledByteBufAllocator申请内存时,首先从PoolThreadLocalCache中获取与线程绑定的缓存池PoolThreadCache,如果不存在线程私有缓存池,则轮询分配一个Arean数组中的PooledArena,创建一个新的PoolThreadCache作为缓存池使用。

PooledArena在进行内存分配时对预分配的内存容量做判断,分为如下几种场景:

(1)需要分配的内存小于PageSize时,分配tiny或者small内存。

(2)需要分配的内存介于PageSize和ChunkSize之间时,则分配normal内存。

(3)需要分配的内存大于ChunkSize时,则分配huge内存(非池化内存)。

Netty内存池将内存分为几类:tiny(小于512B)、small(大于等于512B,小于8KB)、normal(大于等于8KB,小于等于16MB)和huge(大于16MB),系统根据需要申请的内存大小选择合适的MemoryRegionCache。

在PooledArena中创建PoolChunk后,调用PoolChunk的allocate()方法进行真正的内存分配:PoolChunk通过二叉树记录每个PoolSubpage的分配情况,如图3-15所示。

PoolChunk用memoryMap和depthMap来表示二叉树,其中memoryMap存放的是PoolSubpage的分配信息,depthMap存放的是二叉树的深度。depthMap初始化之后就不再变化,而memoryMap则随着PoolSubpage的分配而改变。初始化时,memoryMap和depthMap的取值相同。节点的分配情况有如下三种可能。

(1)memoryMap[id] = depthMap[id]:表示当前节点可分配内存。

(2)memoryMap[id] > depthMap[id]:表示当前节点至少一个子节点已经被分配,无法分配满足该深度的内存,但是可以分配更小一些的内存(通过空闲的子节点)。

(3)memoryMap[id] = 最大深度(默认为11) + 1:表示当前节点下的所有子节点都已经分配完,没有可用内存。

假设申请4KB的内存,内存分配过程如图3-16所示。

节点被标记为被占用之后,依次向上遍历更新父节点,直到根节点。将父节点的memoryMap[id]位置信息修改为两个子节点中的较小值,如图3-17所示。

获取到合适的节点之后,根据节点ID计算并获取subpageIdx,通过subpageIdx从PoolSubpage<T>[] subpages中获取可用的PoolSubpage。如果PoolSubpage为空,则新建PoolSubpage对象,并将其加入PoolChunk的PoolSubpage<T>[] subpages中,就可以参与后续的内存分配了。如果PoolSubpage不为空,说明是被使用完之后释放到了内存池中,重新初始化PoolSubpage,并将其加入内存池的双向链表中,参与内存分配。

调用PoolSubpage的allocate方法,返回代表PoolSubpage块存储区域的占用情况结果(long类型:高32位表示subPage中分配的位置,低32位表示二叉树中分配的节点),PoolArena根据上述信息调用PoolChunk的initBuf方法完成PooledByteBuf的内存分配。

展开
目录

第1章 Netty服务端意外退出案例 1

1.1 Netty服务端意外退出问题 1

1.1.1 Java Daemon线程简介 2

1.1.2 Netty服务端启动原理 4

1.1.3 如何防止Netty服务端意外退出 6

1.1.4 实际项目中的优化策略 8

1.2 Netty优雅退出机制 9

1.2.1 Java优雅退出机制 10

1.2.2 Java优雅退出的注意点 12

1.2.3 Netty优雅退出机制 14

1.2.4 Netty优雅退出原理和源码分析 15

1.2.5 Netty优雅退出的一些误区 20

1.3 总结 21

第2章 Netty客户端连接池资源泄漏案例 22

2.1 Netty连接池资源泄漏问题 22

2.1.1 连接池创建代码 23

2.1.2 内存溢出和线程膨胀 23

2.1.3 错用NIO编程模式 25

2.1.4 正确的连接池创建方式 26

2.1.5 并发安全和资源释放 28

2.2 Netty客户端创建机制 29

2.2.1 Java NIO客户端创建原理分析 29

2.2.2 Netty客户端创建原理分析 32

2.2.3 Bootstrap工具类源码分析 34

2.3 总结 36

第3章 Netty内存池泄漏疑云案例 37

3.1 Netty内存池泄漏问题 37

3.1.1 路由转发服务代码 38

3.1.2 响应消息内存释放玄机 39

3.1.3 采集堆内存快照分析 42

3.1.4 ByteBuf申请和释放的理解误区 45

3.2 Netty内存池工作机制 48

3.2.1 内存池的性能优势 48

3.2.2 内存池工作原理分析 51

3.2.3 内存池核心代码分析 54

3.3 总结 58

第4章 ByteBuf故障排查案例 59

4.1 HTTP协议栈ByteBuf使用问题 59

4.1.1 HTTP响应Body获取异常 59

4.1.2 ByteBuf非法引用问题 63

4.1.3 ByteBuf使用注意事项 66

4.2 Netty ByteBuf实现机制 67

4.2.1 Java原生ByteBuffer的局限性 67

4.2.2 Netty ByteBuf工作原理分析 67

4.2.3 ByteBuf引用计数器工作原理和源码分析 70

4.3 总结 73

第5章 Netty发送队列积压导致内存泄漏案例 74

5.1 Netty发送队列积压案例 74

5.1.1 高并发故障场景 74

5.1.2 内存泄漏原因分析 76

5.1.3 如何防止发送队列积压 78

5.1.4 其他可能导致发送队列积压的因素 80

5.2 Netty消息发送工作机制 82

5.2.1 WriteAndFlushTask原理和源码分析 83

5.2.2 ChannelOutboundBuffer原理和源码分析 86

5.2.3 消息发送源码分析 88

5.2.4 消息发送高低水位控制 94

5.3 总结 95

第6章 API网关高并发压测性能波动案例 96

6.1 高并发压测性能波动问题 96

6.1.1 故障场景模拟 96

6.1.2 性能波动原因定位 98

6.1.3 主动内存泄漏定位法 101

6.1.4 网关类产品的优化建议 102

6.2 Netty消息接入内存申请机制 102

6.2.1 消息接入的内存分配原理和源码分析 102

6.2.2 Netty ByteBuf的动态扩容原理和源码分析 107

6.3 总结 108

第7章 Netty ChannelHandler并发安全案例 109

7.1 Netty ChannelHandler并发安全问题 109

7.1.1 串行执行的ChannelHandler 110

7.1.2 跨链路共享的ChannelHandler 114

7.1.3 ChannelHandler的并发陷阱 116

7.2 Netty ChannelHandler工作机制 118

7.2.1 职责链ChannelPipeline原理和源码分析 118

7.2.2 用户自定义Event原理和源码分析 122

7.3 总结 123

第8章 车联网服务端接收不到车载终端消息案例 124

8.1 车联网服务端接收不到车载终端消息问题 124

8.1.1 故障现象 125

8.1.2 故障期线程堆栈快照分析 126

8.1.3 NioEventLoop线程防挂死策略 128

8.2 NioEventLoop线程工作机制 129

8.2.1 I/O读写操作原理和源码分析 130

8.2.2 异步任务执行原理和源码分析 133

8.2.3 定时任务执行原理和源码分析 135

8.2.4 Netty多线程最佳实践 137

8.3 总结 137

第9章 Netty 3.X版本升级案例 139

9.1 Netty 3.X的版本升级背景 139

9.1.1 被迫升级场景 140

9.1.2 升级不当遭遇各种问题 140

9.2 版本升级后数据被篡改问题 141

9.2.1 数据篡改原因分析 142

9.2.2 问题总结 143

9.3 升级后上下文丢失问题 143

9.3.1 上下文丢失原因分析 144

9.3.2 依赖第三方线程模型的思考 144

9.4 升级后应用遭遇性能下降问题 145

9.4.1 性能下降原因分析 145

9.4.2 性能优化建议 146

9.5 Netty线程模型变更分析 147

9.5.1 Netty 3.X版本线程模型 147

9.5.2 Netty 4.X版本线程模型 149

9.5.3 线程模型变化点源码分析 150

9.5.4 线程模型变化总结 152

9.6 总结 154

第10章 Netty并发失效导致性能下降案例 155

10.1 业务ChannelHandler无法并发执行问题 155

10.1.1 服务端并发设计相关代码分析 155

10.1.2 无法并行执行的EventExecutorGroup 159

10.1.3 并行执行优化策略和结果 161

10.2 Netty DefaultEventExecutor工作机制 163

10.2.1 DefaultEventExecutor原理和源码分析 164

10.2.2 业务线程池优化策略 165

10.2.3 Netty线程绑定机制原理和源码分析 168

10.3 总结 170

第11章 IoT百万长连接性能调优案例 171

11.1 海量长连接接入面临的挑战 171

11.1.1 IoT设备接入特点 172

11.1.2 IoT服务端性能优化场景 172

11.1.3 服务端面临的性能挑战 172

11.2 智能家居内存泄漏问题 173

11.2.1 服务端内存泄漏原因定位 173

11.2.2 问题背后的一些思考 174

11.3 操作系统参数调优 174

11.3.1 文件描述符 175

11.3.2 TCP/IP相关参数 175

11.3.3 多网卡队列和软中断 177

11.4 Netty性能调优 177

11.4.1 设置合理的线程数 177

11.4.2 心跳优化 180

11.4.3 接收和发送缓冲区调优 183

11.4.4 合理使用内存池 184

11.4.5 防止I/O线程被意外阻塞 185

11.4.6 I/O线程和业务线程分离 187

11.4.7 针对端侧并发连接数的流控 187

11.5 JVM相关性能优化 189

11.5.1 GC调优 189

11.5.2 其他优化手段 193

11.6 总结 193

第12章 静态检查修改不当引起性能下降案例 195

12.1 Edge Service性能严重下降问题 195

12.1.1 Edge Service热点代码分析 195

12.1.2 静态检查问题不是简单的一改了之 197

12.1.3 问题反思和改进 200

12.2 克隆和浅拷贝 201

12.2.1 浅拷贝存在的问题 201

12.2.2 Netty的对象拷贝实现策略 203

12.3 总结 204

第13章 Netty性能统计误区案例 205

13.1 时延毛刺排查相关问题 205

13.1.1 时延毛刺问题初步分析 205

13.1.2 服务调用链改进 207

13.1.3 都是同步思维惹的祸 208

13.1.4 正确的消息发送速度性能统计策略 209

13.1.5 常见的消息发送性能统计误区 212

13.2 Netty关键性能指标采集策略 212

13.2.1 Netty I/O线程池性能指标 213

13.2.2 Netty发送队列积压消息数 214

13.2.3 Netty消息读取速度性能统计 215

13.3 总结 215

第14章 gRPC的Netty HTTP/2实践案例 216

14.1 gRPC基础入门 216

14.1.1 RPC框架简介 216

14.1.2 当前主流的RPC框架 218

14.1.3 gRPC框架特点 218

14.1.4 为什么选择HTTP/2 219

14.2 gRPC Netty HTTP/2服务端工作机制 220

14.2.1 Netty HTTP/2服务端创建原理和源码分析 220

14.2.2 服务端接收HTTP/2请求消息原理和源码分析 224

14.2.3 服务端发送HTTP/2响应消息原理和源码分析 231

14.3 gRPC Netty HTTP/2客户端工作机制 234

14.3.1 Netty HTTP/2客户端创建原理和源码分析 235

14.3.2 客户端发送HTTP/2请求消息原理和源码分析 238

14.3.3 客户端接收HTTP/2响应消息原理和源码分析 242

14.4 gRPC消息序列化机制 243

14.4.1 Google Protobuf简介 243

14.4.2 消息的序列化原理和源码分析 244

14.4.3 消息的反序列化原理和源码分析 245

14.5 gRPC线程模型 246

14.5.1 服务端线程模型 246

14.5.2 客户端线程模型 247

14.5.3 线程模型总结 248

14.6 总结 249

第15章 Netty事件触发策略使用不当案例 250

15.1 channelReadComplete方法被调用多次问题 250

15.1.1 ChannelHandler调用问题 250

15.1.2 生产环境问题模拟重现 252

15.2 ChannelHandler使用的一些误区总结 255

15.2.1 channelReadComplete方法调用 255

15.2.2 ChannelHandler职责链调用 257

15.3 总结 258

第16章 Netty流量整形应用案例 259

16.1 Netty流量整形功能 259

16.1.1 通用的流量整形功能简介 260

16.1.2 Netty流量整形功能简介 260

16.2 Netty流量整形应用 261

16.2.1 流量整形示例代码 261

16.2.2 流量整形功能测试 263

16.3 Netty流量整形工作机制 264

16.3.1 流量整形工作原理和源码分析 264

16.3.2 并发编程在流量整形中的应用 271

16.3.3 使用流量整形的一些注意事项总结 274

16.4 总结 278

第17章 Netty SSL应用案例 279

17.1 Netty SSL功能简介 279

17.1.1 SSL安全特性 280

17.1.2 Netty SSL实现机制 281

17.2 Netty客户端SSL握手超时问题 282

17.2.1 握手超时原因定位 282

17.2.2 Netty SSL握手问题定位技巧 283

17.3 SSL握手性能问题 284

17.3.1 SSL握手性能热点分析 284

17.3.2 缓存和对象池 285

17.4 SSL事件监听机制 286

17.4.1 握手成功事件 286

17.4.2 SSL连接关闭事件 286

17.5 总结 287

第18章 Netty HTTPS服务端高并发宕机案例 288

18.1 Netty HTTPS服务端宕机问题 288

18.1.1 客户端大量超时 288

18.1.2 服务端内存泄漏原因分析 289

18.1.3 NioSocketChannel泄漏原因探究 290

18.1.4 高并发场景下缺失的可靠性保护 292

18.2 功能层面的可靠性优化 294

18.2.1 Netty HTTPS服务端可靠性优化 295

18.2.2 HTTPS客户端优化 296

18.3 架构层面的可靠性优化 297

18.3.1 端到端架构问题剖析 297

18.3.2 HTTP Client切换到NIO 298

18.3.3 同步RPC调用切换到异步调用 299

18.3.4 协议升级到HTTP/2 303

18.4 总结 307

第19章 MQTT服务接入超时案例 308

19.1 MQTT服务接入超时问题 308

19.1.1 生产环境问题现象 308

19.1.2 连接数膨胀原因分析 309

19.1.3 无效连接的关闭策略 309

19.1.4 问题总结 310

19.2 基于Netty的可靠性设计 311

19.2.1 业务定制I/O异常 311

19.2.2 链路的有效性检测 312

19.2.3 内存保护 313

19.3 总结 315

第20章 Netty实践总结 316

20.1 Netty学习策略 316

20.1.1 入门知识准备 316

20.1.2 Netty入门学习 319

20.1.3 项目实践 319

20.1.4 Netty源码阅读策略 319

20.2 Netty故障定位技巧 320

20.2.1 接收不到消息 320

20.2.2 内存泄漏 321

20.2.3 性能问题 322

20.3 总结 322

展开
加入书架成功!
收藏图书成功!
我知道了(3)
发表书评
读者登录

请选择您读者所在的图书馆

选择图书馆
浙江图书馆
点击获取验证码
登录
没有读者证?在线办证