Netty系列-Netty线程模型
# 单Reactor多线程模型

# 单Reactor多线程模型分析
- Reactor实例通过select监控客户端请求事件,收到事件请求通过Dispatch进行分发。
- 如果建立链接请求,则由Acceptor通过accept处理连接请求,然后创建Handler对象处理完成连接后的业务操作。
- 如果不是连接请求,则由reactor分发调用连接对应的handler来处理。
- handler只负责响应事件,不做具体的业务处理,通过read读取数据后,会分发给worker线程池中的某个线程处理业务。
- worker线程池会分配独立的线程完成真正的业务,并将结果返回给handler。
- handler收到结果后通过send将结果返回给客户端 优点: 可以充分利用多核CPU的处理能力。 缺点: 多线程会数据共享和访问比较复杂,reactor处理了所有的事件的监听和相应,在单线程运行,在高并发场景容易出现性能瓶颈。
# 主从Reactor多线程模型
针对单Reactor多线程模型中,Reactor在单线程中运行,高并发场景下会成为性能瓶颈,则产生的让Reactor运行在多线程中。

# 主从Reactor多线程模型分析
- Reactor主线程MainReactor对象通过select监听链接事件,收到事件请求通过Acceptor处理连接事件。
- 当Acceptor处理连接事件后,MainReactor将连接分配给subReactor。
- subReactor将链接加入链接队列进行监听,并创建handler进行各种事件处理。
- 有新的事件发生时, subReacto将调用相应的handler处理。
- read读取数据后,会分发给worker线程进行业务处理。
- worker线程池会分配独立的线程完成真正的业务,并将结果返回r。
- handler收到结果后通过send将结果返回给客户端。
Reactor主线程可以对应多个Reactor子线程,即Reactor主线程可以和Reactor子线程相关联。 优点:
父线程与子线程的数据交互简单,职责明确,父线程只需要接收新连接,子线程完成后续的业务处理 父线程与子线程的数据交互简单,Reactor主线程只需要把新连接传给子线程,子线程无需返回数据 缺点:
编程复制读较高。
# Netty模型
netty 的线程模型并不是一成不变的,它实际取决于用户的启动参数配置。通过设置不同的启动参数,Netty 可以同时支持 Reactor 单线程模型、多线程模型。
# 简单版
Netty主要基于主从Reactor多线程模型做了一定改进

- BossGrop线程维护Selector,只关注Accept;
- 当接受到Accept事件,获取对应的SocketChannel,封装成NIOSocketChannel并注册到Work线程(事件循环),并进行维护。
- 当Worker线程监听到Selector中通道发生自己感兴趣的事件后,进行处理(handler)。
# 完整版

- Netty抽象出两组线程池BossGroup专门负责接受客户端的链接,WorkerGroup专门负责网络的读写。
- BossGroup与WorkerGroup都是NioEventLoopGroup
- NioEventLoopGroup为事件循环组,组内含有多个事件循环,每个事件循环都是NioEventLoop。
- NioEventLoop表示不断循环的执行处理任务的线程,每个NioEventLoop都有一个Selector,用于监听绑定在其上的Socket网络通讯。
- NioEventLoopGroup可以有多个线程,含有多个NioEventLoop。
- BossNioEventLoop循环执行三步骤:
- 轮询accept事件
- 处理accept事件,与client建立连接,生成NioSocketChannel,并将其注册到某个worker NioEventLoop上的Selector。
- 处理任务队列的任务,即runAllTasks
- Worker NioEventLoop循环执行步骤:
- 轮询read、write事件。
- 在相应NioSocketChannel的处理I/O事件
- 处理任务队列的任务,即runAllTasks
- Worker NioEventLoop在处理数据时会使用Pipline(管道),Pipline中包含channel。
上次更新: 2020/07/25, 16:07:00