跳转至

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 处理,避免并发问题。
Boss (accept) -> 分发到 Worker
Worker (read/write) -> Pipeline -> Handler

四、零拷贝

Netty 的"零拷贝"有几层:

  1. CompositeByteBuf:把多个 ByteBuf 逻辑上合并,不真正拷贝内存。
  2. FileRegion:底层用 sendfile 系统调用,数据直接从文件到 Socket。
  3. ByteBuf 池化:PooledByteBufAllocator 复用内存,减少 GC。

注意:Netty 的零拷贝不是 OS 层面的 mmap,而是应用层的优化。

五、ByteBuf

比 JDK ByteBuffer 强在:

  • 可读、可写两个指针,不需要 flip。
  • 池化复用。
  • 支持堆外内存(Direct Memory)。
  • 自动扩容。

六、Pipeline 与 ChannelHandler

每个 Channel 有一条 Pipeline,串着多个 Handler:

Head -> Handler1 (入站) -> Handler2 (入站) -> ... -> Tail
              <- Handler3 (出站) <- Handler4 (出站)

入站:channelRead,从 Head 到 Tail。 出站:write,从 Tail 到 Head。

七、内存管理

  • PooledByteBufAllocator:默认开启,内存池。
  • 引用计数:release() 释放,不用 finalize。
  • 堆外内存不受 JVM GC 管辖,要手动释放,否则 OOM。

八、为什么 Netty 快

  1. 异步非阻塞 IO,少量线程处理大量连接。
  2. 零拷贝。
  3. 内存池减少 GC。
  4. 高效的编解码。
  5. 无锁设计(EventLoop 线程模型)。

九、常见应用

  • RPC 框架:Dubbo、gRPC。
  • MQ:RocketMQ。
  • 网关:Spring Cloud Gateway、Zuul。
  • 游戏服务器。
  • 微服务网关。

高频追问

  • 为什么默认 BossGroup 1 个线程?accept 操作很快,一个够了。
  • WorkerGroup 默认 2*CPU 核数。
  • 粘包拆包:用 LengthFieldBasedFrameDecoder 解决。