概述

入坑 Netty 已有月余,主要还是接触 Vert.x ,并未有太多机会直接写 Netty。
也尝试在网上看了许多的源码解析,但是总是没有一个提纲来完整的表述整个 Netty 的完整处理流程。
我这里尝试用流程图的方法,解析 Netty 主要的几个Netty主要的处理流程。主要是主流程和Pipeline
对于 ByteBuf、各种 Decoder ,我这里也不再详细解析,有兴趣可以再看网上的解析。

Netty运行时处理请求的流程

说明:

  1. 每个 Eventloop 都有自己的一个 Selector,我为了画图方便,改为共用一个 Selector
  2. Boss Eventloop负责 ACCEPT 事件,他在启动的时候向 Selector 注册 ACCPET 事件和 ServerChannel,并且绑定端口
  3. Work EventloopGroup 是一组 Work Eventloop 的集合,数量默认为 CPU 核心数 *2
  4. Work Eventloop 本质上是一个线程,他有一个死循环,执行两种事件:READ事件和自己任务队列上面的事件
  5. Work Eventloop 的任务队列上面的事件是可以在任何地方提交加入(通过 Future/Promise 的 addListener 方法提交任务)
  6. Pipeline 是在我们启动的 Netty 的时候指定的,是我们的任务代码
  7. Buffer 是缓冲区,缓冲我们的数据,并且一次写入。
  8. Channel 是和用户连接的桥梁,往 Channel 写数据就是往用户电脑写数据
  9. Pipeline 处理时可以选择同步模式还是异步模式,但无论如何最终都要刷写 Buffer ,最后要结束数据流。

Netty Pipeline 流程

InBound 操作的流水线

Inbound的方法一般由系统Netty帮我们调用
ChannelRegister: 客户 Channel 注册到 Eventloop 里面会发送事件 (第一次连接)
ChannelActive: 客户 Channel 连接的时候Channel会发送事件 (从未连接到已连接)
ChannelRead: 客户的数据已经存了一部分到系统缓冲区的时候会发送事件 (从未发送数据到已发送数据)
ChannelReadComplete: 缓冲区里面已经没有数据会发送事件(从发送数据到发送数据完成)
调用的流程是一致的,主要用到的是 ChannelRead

说明:

  1. HandlerContext是 Pipeline 的每一个节点,从而组成一个双向链表结构。每个 HandlerContext 包含以下内容:
    1. 自定义的Handler对象
    2. 用户 Channel
    3. 关联的 Eventloop
    4. Inbound 和 OutBound 的触发器
    5. ByteBuffer 内存分配器
  2. 添加 Channel Handler 的方法
    1. 在 Bootstrap 中 .childHandler() ch.pipeline().addLast()
    2. 可以添加 Inbound 和 OutBound

OutBound操作流水线

一般是主动调用,而不是Netty自动调用
bind 操作
connect 操作
disconnect 操作
read 操作 (一般不用,用Inbound的自动Read)
write 操作
deregister 操作

异常处理流水线

业务中的流水线

这里只是给一个参考