Skip to content

Netty技术栈总览

一句话定位:Netty 是异步事件驱动的网络应用框架,封装 JDK 原生 NIO 的复杂度,用「Channel → EventLoop(线程)→ ChannelPipeline(Handler 链)」三大抽象把网络编程变成流水线;Dubbo / RocketMQ / Elasticsearch / gRPC 都拿它当通信底座。

为什么不用 JDK 原生 NIO(四大痛点)

痛点说明
API 繁杂Selector / ServerSocketChannel / ByteBuffer 等类库难上手
门槛高涉及 Reactor 模式,需要多线程 + 网络编程双技能
可靠性补齐难断连重连、闪断、半包读写、失败缓存都要自己处理
epoll bugSelector 空轮询导致 CPU 100%;JDK 6u18 声称修复但 1.7 仍存在

Netty 的价值 = 简化使用 + 内置可靠性 + 修复 JDK bug + 高性能。

核心组件地图

组件职责
Channel网络操作抽象(bind/connect/read/write);NioServerSocketChannel(服务端)/ NioSocketChannel(客户端)
EventLoop监听网络事件并调用 Handler 处理 I/O;1 个 EventLoop = 1 个线程 + 1 个 Selector,处理多个 Channel
EventLoopGroupEventLoop 线程池;默认线程数 = CPU 核数 × 2
ChannelFuture异步操作结果占位;addListener() 注册回调,sync() 转同步
ChannelHandler处理入站/出站事件(Inbound / Outbound / Duplex)
ChannelPipelineHandler 链容器;入站 head→tail,出站 tail→head,双向链表
ChannelHandlerContext保存 Channel 上下文,关联一个 Handler,负责链上传播
Bootstrap / ServerBootstrap客户端/服务端启动引导类(串联所有组件)

组件协作关系

Channel 创建时自动绑定专属 ChannelPipeline(永久关联)
ChannelPipeline = ChannelHandlerContext 双向链表
每个 Context 关联一个 ChannelHandler
EventLoop 驱动:I/O 就绪事件 → 沿 Pipeline 传播 → Handler 处理
  • 入站事件(读/连接):由 I/O 线程产生,head 向后传到最后一个 Inbound Handler。
  • 出站事件(写):从 tail 向前传到第一个 Outbound Handler,由 Unsafe 执行真正写。

为什么快(高性能五板斧)

  1. Reactor 线程模型:bossGroup 收连接(MainReactor),workerGroup 处理读写(SubReactor + Worker 同池),同步非阻塞用最少线程做最多事。
  2. 零拷贝:Direct Buffer 直连内存 + CompositeByteBuf 逻辑合并 + FileRegion(transferTo) 文件直传。
  3. 内存池:Arena→Chunk(2048 page)→Page 分级,PooledByteBuf 复用内存、引用计数回收,降 GC。
  4. 串行无锁化:每个 Channel 的读写都在同一 EventLoop 线程内串行完成,无锁竞争。
  5. 粘包解码 + 心跳:内置 LineBased/DelimiterBased/FixedLength/LengthFieldBased 解码器;IdleStateHandler 心跳检测。

应用场景

  • RPC 通信底座:Dubbo 默认 Netty 通信、RocketMQ 通信、gRPC。
  • 游戏/IM/推送:自研私有协议栈,TCP/UDP/HTTP 都支持。
  • 大数据:Hadoop Avro RPC 基于 Netty。
  • 可自定义协议实现 HTTP/FTP/WebSocket/Redis Proxy/MySQL Proxy 服务器。

版本

  • Netty 4:主流稳定版,推荐使用。
  • Netty 5:用了 ForkJoinPool,复杂度↑ 性能改善不明显,不推荐(官网无下载)。

常见误解

  • 以为 Netty 是 Web 服务器 → 它是网络应用框架,Tomcat 是 Servlet 容器;Netty 能自己实现 HTTP 服务器,但不等于 Tomcat。
  • 以为一个线程只能处理一个连接 → 一个 EventLoop 线程可管理成百上千个 Channel(I/O 多路复用)。
  • 以为 Netty 全异步就没阻塞 → I/O 是异步的,但业务 Handler 阻塞会卡死该 EventLoop 线程(所有该线程上的 Channel 都受影响),长任务要丢业务线程池。

关联

最近更新