Netty 原理理解¶
一、Netty 是什么¶
异步事件驱动的网络应用框架,用于快速开发高性能、高可靠的网络程序。Dubbo、RocketMQ、gRPC、Spring Cloud Gateway 都用它。
二、核心组件¶
| 组件 | 作用 |
|---|---|
| EventLoop | 处理一个 Channel 的所有 IO 事件 |
| Channel | Socket 抽象 |
| ChannelPipeline | 拦截器链,处理入站/出站事件 |
| ChannelHandler | 具体业务处理逻辑 |
| ByteBuf | 字节缓冲区,比 JDK ByteBuffer 好用 |
| Bootstrap | 启动引导 |
三、Reactor 线程模型¶
Netty 采用主从 Reactor 多线程模型:
- BossGroup:接收新连接(accept)。
- WorkerGroup:处理已建立连接的读写。
- 每个 EventLoop 绑定一个线程,一个 Channel 生命周期内只由一个 EventLoop 处理,避免并发问题。
四、零拷贝¶
Netty 的"零拷贝"有几层:
- CompositeByteBuf:把多个 ByteBuf 逻辑上合并,不真正拷贝内存。
- FileRegion:底层用 sendfile 系统调用,数据直接从文件到 Socket。
- ByteBuf 池化:PooledByteBufAllocator 复用内存,减少 GC。
注意:Netty 的零拷贝不是 OS 层面的 mmap,而是应用层的优化。
五、ByteBuf¶
比 JDK ByteBuffer 强在:
- 可读、可写两个指针,不需要 flip。
- 池化复用。
- 支持堆外内存(Direct Memory)。
- 自动扩容。
六、Pipeline 与 ChannelHandler¶
每个 Channel 有一条 Pipeline,串着多个 Handler:
入站:channelRead,从 Head 到 Tail。
出站:write,从 Tail 到 Head。
七、内存管理¶
- PooledByteBufAllocator:默认开启,内存池。
- 引用计数:
release()释放,不用 finalize。 - 堆外内存不受 JVM GC 管辖,要手动释放,否则 OOM。
八、为什么 Netty 快¶
- 异步非阻塞 IO,少量线程处理大量连接。
- 零拷贝。
- 内存池减少 GC。
- 高效的编解码。
- 无锁设计(EventLoop 线程模型)。
九、常见应用¶
- RPC 框架:Dubbo、gRPC。
- MQ:RocketMQ。
- 网关:Spring Cloud Gateway、Zuul。
- 游戏服务器。
- 微服务网关。
高频追问
- 为什么默认 BossGroup 1 个线程?accept 操作很快,一个够了。
- WorkerGroup 默认 2*CPU 核数。
- 粘包拆包:用 LengthFieldBasedFrameDecoder 解决。