对于Reactor模型的具体介绍以及3种模型的实现这里就不多介绍了,网上有大量参考的资料,这里只做简要讲述,重点是阐述Netty中对Reactor模型的实现
Reactor模型的核心思想是将关注的IO事件注册到多路复用器上,一旦有 I/O 事件触发,将事件分发到事件处理器中,执行就绪 I/O 事件对应的处理函数中。模型中有三个重要的组件:
- 多路复用器:由操作系统提供接口,Linux 提供的 I/O 复用接口有select、poll、epoll 。
- 事件分离器:将多路复用器返回的就绪事件分发到事件处理器中。
- 事件处理器:处理就绪事件处理函数。
0x01 Reactor 线程模型
- Reactor单线程模型:所有的IO操作都由同一个NIO线程处理。
使用的是异步非阻塞IO,所有的IO操作都不会导致阻塞,理论上一个线程可以独立处理所有IO相关的操作。但是即使线程利用率达到100%,也不会能撑住太高的并发。
- Reactor多线程模型:Reactor多线程模型与单线程模型最大的区别就是有一组NIO线程来处理IO操作。
有专门一个NIO线程—-Acceptor线程用于监听服务端,接收客户端的TCP连接请求,网络IO操作—-读、写等由一个NIO线程池负责。瓶颈在于客户端同时连接数,毕竟是一个线程再做监听工作。
- 主从Reactor模型:服务端用于接收客户端连接的不再是一个单独的NIO线程,而是一个独立的NIO线程池。后续操作与2类似。
官方推荐模型,可以解决一个服务端监听线程无法有效处理所有客户端连接的性能不足问题。
0x02 Netty 模型
其中Netty NIO 为多Reactor 多线程模型的变种,mainReactor负责监听ServerSocketChannel,用来处理客户端新连接的建立,并将建立的客户端的 SocketChannel 指定注册给 subReactor 。subReactor 维护自己的 Selector ,基于 mainReactor 建立的客户端的 SocketChannel 多路分离 IO 读写事件,读写网络数据。对于业务处理的功能,另外扔给 worker 线程池来完成。图例如下
0x03 Netty NIO 客户端
- 对于一个Netty NIO客户端来说一个EventLoop对应的是一个Reactor。
- 一个 Bootstrap 的启动,只能发起对一个远程的地址。所以只会使用一个 NIO Selector ,也就是说仅使用一个 Reactor 。即使,我们在声明使用一个 EventLoopGroup ,该 EventLoopGroup 也只会分配一个 EventLoop 对 IO 事件进行处理。
所以我们可以认为我Netty NIO客户端是一种【Reactor 单线程模型】
(注:Dubbo 或 Motan 这两个 RPC 框架,支持通过配置,同一个 Consumer 对同一个 Provider 实例同时建立多个客户端连接。可以算是Reactor多线程模型,但我们一般传统意义上的Netty客户端是单线程模型)
1 | // 创建一个 EventLoopGroup 对象 |
0x04 Netty NIO 服务端
1 | // 创建两个 EventLoopGroup 对象 |
对于 Netty NIO 服务端来说,创建两个 EventLoopGroup 。
bossGroup
对应 Reactor 模式的 mainReactor ,用于服务端接受客户端的连接。比较特殊的是,传入了方法参数nThreads = 1
,表示只使用一个 EventLoop ,即只使用一个 Reactor 。这个也符合我们上面提到的,“通常,mainReactor 只需要一个,因为它一个线程就可以处理”。workerGroup
对应 Reactor 模式的 subReactor ,用于进行 SocketChannel 的数据读写。对于 EventLoopGroup ,如果未传递方法参数nThreads
,表示使用 CPU 个数 Reactor 。这个也符合我们上面提到的,“通常,subReactor 的个数和 CPU 个数相等,每个 subReactor 独占一个线程来处理”。
因为使用两个 EventLoopGroup ,所以符合【多 Reactor 多线程模型】的多 Reactor 的要求
0x05 Netty 线程模型
Netty的线程模型并不是一成不变的,它实际取决于用户的启动参数配置。通过设置不同的启动参数,Netty可以同时支持Reactor单线程模型、多线程模型和主从Reactor多线程模型。
所以我们可以把Netty看作是主从多线程模型的变种,大体思想即为boss线程使用多线程来处理客户端连接,对应上文的mainReactor,work线程使用多个子线程处理事件响应,对应上文的subReactor
参考:
精尽 Netty 源码解析 —— EventLoop(一)之 Reactor 模型
- 本文作者: Noisy
- 本文链接: http://Metatronxl.github.io/2019/10/15/Netty-面试题整理-Reactor模型/
- 版权声明: 本博客所有文章除特别声明外,均采用 Apache License 2.0 许可协议。转载请注明出处!