彻底搞懂 Netty 线程模型( 二 )

  • Handler:负责处理非阻塞的行为,标识系统管理的资源,同时将 Handler 与事件绑定 。
  • 注意:Reactor 为单个线程,如上图所示:不仅需要处理客户端的 accept 连接请求,同时也要负责分发(dispatch)读写请求到处理器中 。由于只有单个线程处理各种请求,所以要求处理器中的业务需要能够快速处理完 。
    改进:现在的服务器基本上是多核 CPU,那么在多处理器场景下,为实现服务的高性能我们可以有目的的采用多线程模式处理业务 。
    彻底搞懂 Netty 线程模型

    文章插图
     
    上图为多线程版本事件驱动模型,可以理解为NIO多线程版本
    通过与NIO单线程模型相比,增加了worker线程池,专门用于处理非IO操作(decode、compute、encode),大大提高了工作效率 。
    这种模型下,客户端发送过来的连接和注册还是由主线程 Reactor 统一去处理,只不过客户端连接成功后的后续事件分发给 worker 线程池去处理 。
    但是,当客户端短时间内几十万或者上百万条连接请求的时候(双十一、春运抢票),单个 Rector 不仅要处理注册事件,也要同时分发任务到 worker 线程池,由于分发也是比较耗时的操作,有可能会导致阻塞 。
    继续改进:将Reactor 拆分为两部分
    彻底搞懂 Netty 线程模型

    文章插图
     
    上图为主从NIO模型
    如上图所示,在这种模型下,mainReactor 专门负责新客户端的连接操作,建立通道(channel),然后将一定事件内的 channel 注册到另外一个 subReactor,subReactor 负责将客户端的读写请求交给线程池处理 。这样即使几十万个请求同时到来也无所谓了 。
    通俗理解,mainReactor就是大总管,只负责接口,subReactor就是一个员工,负责给总管接待客户提供服务 。
    Netty线程模型通过对 《 Scalable IO in Java 》里的一些 IO 处理模式理解,Netty的线程模型就是由上面主从NIO模型演变来的,是基于Reactor模型的 。
    如下图所示,Boos Group 就是上面提到的 mainReactor,与上面不同在于 Worker Group,它可以理解为一组 subReactor,即在大总管下面有多个员工来干活,每次接收的客户都均匀分配给不同员工 。Netty 之所以单机支持百万级别并发量,就是因为一主多从的线程模型 。
    彻底搞懂 Netty 线程模型

    文章插图
     
    需要说明的是,Netty 的线程模型并不是一成不变的 。它通常采用一主多从,但是也可以根据实际需要配置启动参数,通过设置不同的启动参数,Netty 可以同时支持 “多主多从” 。
    下面是对上图“一主多从” Netty 模型的详细解释:
    1. Netty 抽象除两组线程池 BossGroup 和 WorkerGroup,BossGroup 专门负责接收客户端的连接,WorkerGroup 专门负责网络的读写 。
    2. BossGroup 和 WorkerGroup 类型都是 NioEventLoopGroup 。
    3. NioEventLoopGroup 相当于一个事件循环线程组,这个组中含有多个事件循环线程,每一个事件循环线程是 NioEventLoop 。
    4. 每个 NioEventLoop 都有一个 selector,用于监听注册在其上的 socketChannel 的网络通讯 。
    5. 每个 Boss NioEventLoop 线程内部循环执行的步骤有 3 步:处理accept事件,与 client 建立连接,生成 NIOSocketChannel;将NioSocketChannel 注册到某个 worker NioEventLoop 上的 selector;处理任务队列的任务,即runAllTasks 。
    6. 每个 worker NIOEvent'Loop线程循环执行的步骤:轮询注册到最近的 selector 上所有的 NioSocketChannel 的 read、write 事件;处理 I/O 事件,即 read、write事件,在对应的NioScoketChannel 处理业务;runAllTask 处理任务队列 TaskQueue 的任务,一些耗时的业务处理一般可以放入 TaskQueue 中,这样不影响数据在 pipeline 中的流动处理 。
    7. 每个 worker NIOEventLoop 处理 NioSocketChannel 业务时,会使用 pipeline (管道),管道中维护来很多 handler 处理器用来处理 channel 中的数据 。
    Netty 模块组件Bootstrap、ServerBootstrapBootstrap 意思是引导,一个 Netty 应用通常由一个 Bootstrap 开始,主要作用是配置整个 Netty程序,通过链式调用串联各个组件 。Netty 中 Bootstrap 类是客户端程序的启动引导类,ServerBootstrap 是服务端 启动引导类 。
    Future、ChannelFuture正如前面介绍,在 Netty 中所有的 IO 操作都是异步的,不能立刻得知消息是否被正确处理 。但是可以过一会等它执行完成或者直接注册一个监听,具体的实现就是通过 Future 和 ChannelFutures,他们可以注册一个监听,当操作执行成功或失败时监听会自动触发注册的监听事件 。


    推荐阅读