概述
入坑 Netty 已有月余,主要还是接触 Vert.x ,并未有太多机会直接写 Netty。
也尝试在网上看了许多的源码解析,但是总是没有一个提纲来完整的表述整个 Netty 的完整处理流程。
我这里尝试用流程图的方法,解析 Netty 主要的几个 Netty 主要的处理流程。主要是主流程和 Pipeline
对于 ByteBuf、各种 Decoder ,我这里也不再详细解析,有兴趣可以再看网上的解析。
Netty 运行时处理请求的流程
说明:
每个 Eventloop 都有自己的一个 Selector,我为了画图方便,改为共用一个 Selector
Boss Eventloop 负责 ACCEPT 事件,他在启动的时候向 Selector 注册 ACCPET 事件和 ServerChannel,并且绑定端口
Work EventloopGroup 是一组 Work Eventloop 的集合,数量默认为 CPU 核心数 *2
Work Eventloop 本质上是一个线程,他有一个死循环,执行两种事件:READ 事件和自己任务队列上面的事件
Work Eventloop 的任务队列上面的事件是可以在任何地方提交加入(通过 Future/Promise 的 addListener 方法提交任务)
Pipeline 是在我们启动的 Netty 的时候指定的,是我们的任务代码
Buffer 是缓冲区,缓冲我们的数据,并且一次写入。
Channel 是和用户连接的桥梁,往 Channel 写数据就是往用户电脑写数据
Pipeline 处理时可以选择同步模式还是异步模式,但无论如何最终都要刷写 Buffer ,最后要结束数据流。
Netty Pipeline 流程
InBound 操作的流水线
Inbound 的方法一般由系统 Netty 帮我们调用
ChannelRegister: 客户 Channel 注册到 Eventloop 里面会发送事件 (第一次连接)
ChannelActive: 客户 Channel 连接的时候 Channel 会发送事件 (从未连接到已连接)
ChannelRead: 客户的数据已经存了一部分到系统缓冲区的时候会发送事件 (从未发送数据到已发送数据)
ChannelReadComplete: 缓冲区里面已经没有数据会发送事件(从发送数据到发送数据完成)
调用的流程是一致的,主要用到的是 ChannelRead
说明:
HandlerContext 是 Pipeline 的每一个节点,从而组成一个双向链表结构。每个 HandlerContext 包含以下内容:
自定义的 Handler 对象
用户 Channel
关联的 Eventloop
Inbound 和 OutBound 的触发器
ByteBuffer 内存分配器
添加 Channel Handler 的方法
在 Bootstrap 中 .childHandler() ch.pipeline().addLast()
可以添加 Inbound 和 OutBound
OutBound 操作流水线
一般是主动调用,而不是 Netty 自动调用
bind 操作
connect 操作
disconnect 操作
read 操作 (一般不用,用 Inbound 的自动 Read)
write 操作
deregister 操作
异常处理流水线
业务中的流水线
这里只是给一个参考