在前面的章节中,我们了解了 Reactor 模型的特点,以及大体讲了一下,Netty 对 Reactor 模型的支持,Netty 推荐使用主从多线程模型,有一个专门的线程用来接收 TCP 连接,另外有专门的线程用来处理 I/O 相关数据。EventLoopGroup 就很好的让 Netty 对 Reactor 支持。
NioEventLoop 是 EventLoop 的实现类,NioEventLoop 并不存粹是一个 I/O 线程,它除了负责 I/O 的读写之外,还兼顾处理一下子两种类型任务:
因为 NioEventLoop 需要处理网络 I/O 的读写事件,所以它必须聚合一个多路复用器对象,即 Selector。NioEventLoop 的执行逻辑是调用其 run 方法,run 方法里面是一个 for 的无限循环,只有当 NioEventLoop 接收到退出指令的时候,才会退出循环,不然的话会一直执行下去。
它在循环过程中,会先判断任务队列里面有没有需要处理的任务,如果有需要处理的任务就会从多路复用器上面获取相关任务,获取准备就绪的 Channel,然后结合 Channel 的 ChannelPipeline 进行相关处理。
EventLoopGroup 是一组 EventLoop 的抽象,一个 EventLoopGroup 当中会包含一个或多个 EventLoop,EventLoopGroup 提供 next 接口,可以从一组 EventLoop 里面按照一定规则获取其中一个 EventLoop 来处理任务。
在 Netty 服务器端编程中我们需要 BossEventLoopGroup 和WorkerEventLoopGroup 两个 EventLoopGroup 来进行工作。
BossEventLoopGroup 通常是一个单线程的 EventLoop,EventLoop 维护着一个注册了 ServerSocketChannel 的 Selector 实例,EventLoop 的实现涵盖 IO 事件的分离,和分发(Dispatcher),EventLoop 的实现充当 Reactor 模式中的分发(Dispatcher)的角色。
所以通常可以将 BossEventLoopGroup 的线程数参数为 1。
BossEventLoop 只负责处理连接,故开销非常小,连接到来,马上按照策略将 SocketChannel 转发给 WorkerEventLoopGroup,WorkerEventLoopGroup 会由 next 选择其中一个 EventLoop 来将这 个SocketChannel 注册到其维护的 Selector 并对其后续的 IO 事件进行处理。