Netty 不是一种网络协议,而是 Java 的异步事件驱动网络框架。它把连接生命周期、事件循环、缓冲区和协议处理器组织成可组合组件,减少手写 Selector 状态机的重复工作。
Table of contents
Open Table of contents
先认识四个核心对象
- Channel:一条可执行读、写、连接、关闭操作的连接抽象。
- EventLoop:持续处理 Channel 的 I/O 事件和已提交任务;一个 Channel 通常固定归属一个 EventLoop。
- ChannelPipeline:按顺序保存处理器的双向流水线。
- ChannelHandler:处理连接、字节、消息、异常等事件的组件。
ServerBootstrap 用来配置监听 Channel 和新接入的子 Channel。option 作用于监听连接,childOption 作用于接入的客户端连接,二者不能混用。
入站和出站方向
入站事件从网络向业务传播,例如连接激活、收到字节和捕获异常;出站事件从业务向网络传播,例如绑定、连接、写和刷新。 处理器顺序会改变结果:一般先把字节解帧,再解码成业务对象,最后执行业务;返回时把响应对象编码为字节。
网络 -> 解帧 -> 解码 -> 业务处理 -> 编码 -> 网络
处理器不能处理事件时,要调用 ctx.fireChannelRead(message) 等方法继续传播。吞掉事件不会报编译错误,却会让后续处理器永远收不到消息。
先在内存中测试协议
运行Netty 长度字段样例下载:
mvn -Dtest=NetworkServerLabTest#framesAndDecodesOneNettyMessage test
EmbeddedChannel 不打开端口,直接把消息送入 Pipeline,适合确定性测试编解码和处理器顺序。端到端 Socket 测试仍然必要,但不应承担全部协议分支测试。
启动与关闭的最小骨架
一个生产服务器通常使用一个 boss group 接受连接,另一个 worker group 处理已接入 Channel。绑定端口返回的是异步 ChannelFuture;启动失败、写失败和关闭都要观察结果。
关闭时先停止接收流量,再等待在途请求,最后调用各组的 shutdownGracefully() 并限制最长等待时间。
Netty 官方文档当前将 4.2 标为稳定推荐版本,4.1 仍为稳定版本。示例固定 4.2.17.Final,生产项目要通过依赖治理流程升级,不能在教程里写动态版本。 参阅Netty 官方文档入口。
不要把业务阻塞藏进 Handler
Channel 的事件通常串行运行在所属 EventLoop 上,这让连接内状态更容易推理。代价是一个慢 Handler 会延迟该循环管理的其他连接。 数据库访问、阻塞式远程调用和大计算要转交有界执行资源,并把完成结果安全地写回 Channel。
下一步
阅读编解码、粘包拆包与背压,给 TCP 字节流定义可验证的消息边界。