3、Reactor线程模型

烟雨 4年前 (2021-09-07) 阅读数 848 #NIO
文章标签 NIO

一、服务器:BIO线程模型

image.png

BIO线程模型,针对每个请求都需要一个线程进行(处理读入数据、业务处理数据、返回响应结果),这个过程中读、写操作均会阻塞绑定的线程,且跟业务处理串行执行,该模式下,并发量过大时会大量创建线程(可通过线程池提前创建,但是治标不治本),发生的大量上下文切换,从而导致CPU资源占用过大,当连接建立后,若当前线程暂无可读数据,则线程会一直阻塞在读操作上,造成线程资源浪费,高并发下可能会造成排队(线程池线程不够了)、响应不及时的问题。

二、服务器:基于NIO下的Reactor线程模型

image.png

上图示意就是个简单的NIO单Reactor单线程处理模型,流程如下:


  1. Reactor对象通过select监听客户端的请求事件,收到事件消息后通过dispatch进行事件分发。

  2. 如果是建连请求,则交由Acceptor对象处理连接请求,然后创建一个Handler对象继续完成后续处理。

  3. 若不是建连请求,则dispatch会调用对应的Handler进行处理,Handler负责完成连接成功后的后续处理(读操作、写操作、业务处理等)。


此模型很简单,易于理解,但是存在一定的问题,比如单线处理程模型下,无法发挥多核CPU的性能,如果Handler上的业务处理很慢,则意味着整个程序无法处理其他连接事件,造成性能问题。

该模式适用于业务处理快速、客户端连接较少的情况。

2.1、优化方案1:引入线程池处理Handler业务逻辑

image.png

本模型充分利用了多核CPU的处理能力,降低了由业务处理引起的性能问题,Reactor线程仅负责接收连接、读写操作。但是Reactor除了负责连接处理外仍然负责读写操作(Handler处理器里面的逻辑),大量的请求下仍然可能仍然存在性能问题。 

2.2、优化方案2:引入线程池并且分离Handler

image.png

主Reactor对象通过select监听客户端的连接事件,收到连接事件后交由Acceptor处理。

Acceptor处理完成后,主Reactor将此连接分配给子Reactor处理,子Reactor将此连接加入连接队列进行事件监听并建立Handler进行后续的各种操作,同上面的模型一致,子Reactor会监听新的事件,如果有新的事件发生,则调用Handler进行相应的处理。

该模型存在两个线程分别处理Reactor事件,主线程只负责处理连接事件,子线程只负责处理读写事件,这样主线程可以处理更多的连接,而不用关心子线程里的读写处理是否会影响到自己。

版权声明

非特殊说明,本文由Zender原创或收集发布,欢迎转载。

上一篇:2、NIO vs BIO 下一篇:1、Netty入门

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

作者文章
热门