Netty线程模型
在这篇博客里我要整理以下两点内容
- Netty的线程模型
- NioEventLoop源码分析
Netty的线程模型:Reactor模式的实现,下面回顾经典的Reactor线程模型。
1、Reactor单线程模型
所有的I/O请求都在同一个NIO线程上进行处理:
- 作为NIO服务端,接受客户点的TCP连接
- 作为NIO客户端,接受服务端的TCP连接
- 读取消息
- 应答消息
单线程模型的缺点:
- 性能不足,一个NIO线程不能应对高并发场景,也不能利用多核CPU的资源。
- 可靠性不足,一旦这个NIO线程出现意外,会导致整个系统通信模块不可用
2、Reactor多线程模型
有一组NIO线程处理I/O操作:
- 有一个专门的NIO线程(Acceptor线程)来处理TCP连接请求
- NIO线程池负责网络I/O读写操作,线程池可以用JDK标准线程池实现,包含一个任务队列和N个可用线程。
- 一个线程可以处理N条链路,但一条链路唯一对应一个NIO线程。
缺点:
在有些特殊场景下回存在性能问题,比如一个NIO线程(Acceptor)负责监听和处理百万并发客户端连接、或者服务端需要对客户端握手进行安全认证,但认证本身损耗性能。
3、主从Reactor多线程模型
- 一个独立的线程池接受客户端连接
- 一个独立的线程池处理I/O读写。
- Acceptor线程接收到客户端连接后,将SocketChannel注册到I/O线程池的某个I/O线程上,由它负责后续的I/O操作。
4、Netty的线程模型
通过设置不同的启动参数,Netty同时支持Reactor单线程、多线程、和主从Reactor多线程模型
服务器端启动的时候,创建两个NioEventLoopGroup,他们是两个独立的Reactor线程池,一个接受TCP连接,另一个处理I/O读写操作。
Netty用于接受客户端请求的线程池职责:
- 接受客户端TCP连接,初始化Channel参数
- 将链路状态变更时间通知给ChannelPipeline
Netty处理I/O操作的线程池职责
- 发送读事件到ChannelPipeline
- 调用ChannelPipeline的消息发送接口
- 执行系统调用Task
- 执行定时任务Task