跳到正文
Elaine Blog
返回

Netty 快速入门:Channel、EventLoop 与 Pipeline

网络与 I/O

Netty 不是一种网络协议,而是 Java 的异步事件驱动网络框架。它把连接生命周期、事件循环、缓冲区和协议处理器组织成可组合组件,减少手写 Selector 状态机的重复工作。

Table of contents

Open Table of contents

先认识四个核心对象

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 字节流定义可验证的消息边界。


分享这篇文章:

上一篇
select、poll 与 epoll:从就绪通知理解高并发 I/O
下一篇
编解码、粘包拆包与背压