Netty使用手册
Netty架构图
![[images/Pasted image 20250711152444.png]]
模块
- io.netty.bootstrap:提供客户端或服务端引导类(如 Bootstrap, ServerBootstrap)
- io.netty.channel: 核心的通道(Channel)抽象、事件循环、处理器(Handler)等 ChannelPipeline
- io.netty.handler:常用的编解码器、协议处理器、空闲检测、SSL等
- io.netty.buffer:自定义的ByteBuf 内存缓冲区管理(替代 JDK ByteBuffer)
- io.netty.util:工具类、定时器、线程池、反射工具等辅助设施
- io.netty.resolver:DNS 名称解析功能
核心组件
Channel
- 表示一个网络连接抽象,如 SocketChannel(TCP)、DatagramChannel(UDP)等。
- Channel 的所有操作都是异步的,返回 ChannelFuture。
EventLoop和EventLoopGroup
- EventLoop: 相当于一个单线程的事件循环器(负责读、写、调度等事件)。
- EventLoopGroup: 多个 EventLoop 的组合,通常绑定一个线程池。
每个 Channel 绑定一个 EventLoop,执行生命周期内所有 I/O 操作。
一般服务端会定义BossGroup和WorkGroup,BossGroup用于接受连接、注册连接。WorkGroup用于处理网络I/O事件。
ChannelPipeline
- 责任链模式实现,每个连接都有自己的 ChannelPipeline。
ChannelHandler
- ChannelHandler:处理具体的读写、编解码逻辑,有两类:
- ChannelInboundHandler: 入站(如 channelRead)
- ChannelOutboundHandler: 出站(如 write, flush)
ByteBuf
- Netty 自定义的 内存数据容器,比 Java NIO 的 ByteBuffer 更强大:
- 支持池化内存(减少 GC)
- 动态扩容、读写索引分离
Bootstrap / ServerBootstrap
- 用于客户端或服务端的启动配置,设置:
- EventLoopGroup
- Channel 类型
- ChannelInitializer(初始化 pipeline)
- 连接参数(如 TCP_NODELAY, SO_KEEPALIVE)
Channel类型
| Channel 类型 | 通信协议 | 用途示例 |
|---|---|---|
NioSocketChannel | TCP | 普通客户端连接(例如 HTTP 客户端) |
NioServerSocketChannel | TCP | 服务端监听 TCP 端口,接受连接 |
NioDatagramChannel | UDP | 基于 UDP 的服务(如 DNS、视频流) |
EmbeddedChannel | 内存通道 | 用于测试 Pipeline,无需真实网络 |
LocalChannel | 本地进程通道 | JVM 内两个线程通信(无网络) |
LocalServerChannel | 本地服务端 | 与 LocalChannel 配合使用 |
EpollSocketChannel(Linux) | TCP | Linux 下基于 epoll 的高性能 socket |
KQueueSocketChannel(macOS) | TCP | macOS 下的高性能 socket 实现 |
ChannelHandler
- 🔵 Inbound Handler(入站,处理读事件)
- 🔴 Outbound Handler(出站,处理写事件)
ChannelHandler在ChannelPipeline中运行, ChannelPipeline是一条 双向传送带:
- 数据“进来”(客户端发来)走 → 从 头部 head 到 尾部 tail
- 数据“出去”(服务器发回)走 ← 从 尾部 tail 到 头部 head
入站事件(客户端发来数据)流程
当客户端向服务器发送数据,会触发如下流程:
makefile
ChannelPipeline: [HeadContext] → h1 → h2 → h3 → [TailContext]
↑ ↑ ↑
ChannelInboundHandler事件触发链:
| 事件 | 会触发的 Handler 方法 |
|---|---|
| 客户端连接 | channelActive() |
| 收到数据 | channelRead() + channelReadComplete() |
| 客户端断开 | channelInactive() |
| 异常发生 | exceptionCaught() |
出站事件(服务器向客户端写数据)流程
当在handler中调用channel.writeAndFlush向客户端写数据时
java
channel.writeAndFlush(msg);会触发出站事件
makefile
ChannelPipeline: [HeadContext] ← o1 ← o2 ← o3 ← [TailContext]
↑ ↑ ↑
ChannelOutboundHandlerNetty 中的 “出站事件从尾(tail)到头(head)传播” 是指:
当你调用 ctx.write() 或 ctx.writeAndFlush() 发数据时,Netty 会从 pipeline 的尾部向前找(靠近头部)所有的出站处理器(Outbound Handler),依次调用它们的 write() 方法,直到数据被写入 socket。
事件触发链
| 操作 | 会触发的 Handler 方法 |
|---|---|
ctx.write() | write()(从当前位置向前) |
ctx.flush() | flush() |
writeAndFlush() | write() + flush() |
完整收发数据生命周期示意图
makefile
[Client] 发数据
↓
NioEventLoop 触发 socket 读事件
↓
pipeline.fireChannelRead(msg)
↓
Inbound handler1.channelRead()
↓
Inbound handler2.channelRead()
↓
最终业务 handler.channelRead() 处理完后:
↓
ctx.writeAndFlush("回应数据")
↓
Outbound handlerN.write()
↓
Outbound handlerN-1.write()
↓
到达 HeadContext,写入 socket