部分引用于 CSDN https://blog.csdn.net/shulianghan/article/details/106480910

1、Reactor模式简介

Reactor模式是高性能网络编程在设计和架构层面的基础模式。

反应器 ( Reactor ) 模式 涉及到两个组件 , 反应器 ( Reactor ) 组件 和 处理者 ( Handler ) 组件 ;

反应器 ( Reactor ) 组件 : 该组件调度分发事件给 处理者 ( Handler ) 组件 , 处理与相应客户端的 IO 事件
① 运行线程 : 反应器 ( Reactor ) 在独立线程中运行 , 该线程只负责事件相关的监听与分发操作 , 不处理具体的业务逻辑 ;
② 监听事件 : 反应器 ( Reactor ) 在线程中监听客户端的请求事件 ;
③ 分发事件 : 反应器 ( Reactor ) 监听到事件后 , 将事件分发给其 处理者 ( Handler ) 组件 处理实际的业务逻辑 ;
处理者 ( Handler ) 组件 : 该 Handler 组件用于 处理实际的业务逻辑 ;

2、Reactor模式 - 图1

2、三种Reactor方案

2.1、单Reactor单线程

image.png

方案说明:
1、客户端发送请求后服务器端Reactor 通过selector监听事件,收到事件后通过dispatch进行分发
2、如果是建立连接请求事件,那么由 Acceptor通过accept处理连接请求,然后创建一个Handler对象处理后续业务操作,如果不是建立连接事件,则Reactor 直接分发连接对应的Handler来进行处理

  • 优点:模型简单,没有多线程、进程通信、竞争的问题,全部都在1个线程中完成
  • 缺点

(1) 容易出现阻塞 : 该模式下 , 只有一个线程 , 处理者 ( Handler ) 每次只能处理一个客户端的请求事件 , 如果客户端数量很多 , 出现高并发情况 , 只能阻塞等待前面的 处理者 ( Handler ) 将事件处理完毕 , 才能轮到后面的事件开始处理 ;
(2) 服务器性能 : 一般的服务器都是多核多线程 CPU , 只跑一个线程 , 浪费了大量服务器性能 ;
(3) 处理延迟 : 当 处理器 ( Handler ) 处理一个客户端的业务逻辑时 , 无法及时响应其它客户端的连接 , 造成延迟 ;
(4) 可靠性问题 : 如果仅有的一个线程运行出现异常 , 整个程序都崩了

  • 使用场景:客户端的数量有限,业务处理非常快速,比如Redis在业务处理的时间复杂度0(1)的情况

2.2、单Reactor多线程

image.png

方案说明:
1、客户端发送请求后服务器端Reactor 通过selector监听事件,收到事件后通过dispatch进行分发
2、如果是建立连接请求事件,那么由 Acceptor通过accept处理连接请求,然后创建一个Handler对象处理后续业务操作,如果不是建立连接事件,则Reactor 直接分发连接对应的Handler来进行处理
3、handler只负责响应事件,不去做具体的业务处理,通过read读取数据后,会分发给worker线程池的某个线程处理业务,worker线程池会分配独立的线程完成真正的业务,并将结果返回给handler
4、hanler收到响应后通过send将结果返回给client

优点 : 充分发挥出服务器多核多线程 CPU 的优势 , 根据 CPU 性能定制线程个数 , 没有性能上的浪费 ;
缺点 :
(1) 数据同步 : 线程池 ( Worker ) 中的多个业务逻辑处理线程 , 需要与 处理器 ( Handler ) 共享数据 , 涉及到数据跨线程传输访问 , 比较复杂 ;
(2) 反应器 ( Reactor ) 负载较大 : 反应器 ( Reactor ) 处理所有的客户端的事件的监听与分发操作 , 在单线程中运行 , 如果并发数量很高 , 也是有线程堵塞的性能瓶颈产生

2.3、主从Reactor多线程

image.png

方案说明:**
1、客户端发送请求后服务器端Reactor主线程MainReactor 通过selector监听连接事件,收到事件后通过Acceptor处理连接事件
2、当Acceptor处理连接事件后,MainReactor就会把连接分配给SubReactor
3、SubReactor将连接加入到连接队列进行读写监听,并创建相应的处理Handler
4、当有事件发生时,SubReactor就会调用对应的Handler进行处理
5、Handler通过read读取数据,并分发(dispatch)给下面的worker线程池来处理
6、worker线程池为每一个数据处理业务分配一个独立的thread,并返回处理的结果
7、Handler收到worker线程处理的结果后,再通过send将结果返回给Client
8、Reactor主线程可以对应多个子Reactor线程,即MainReactor可以对应多个SubReactor

优点:
父线程和子线程职责分明,主(boss)只负责接待(accept),子(worker)完成具体的业务处理
父线程与子线程的数据交互简单,Reactor主线程只需要把新连接(socketChannel)传递给子线程,子线程无需返回数据

缺点:编程复杂度高( 所以Netty对象NIO进行了封装),随之而来的就是学习升本的提升

2.4、三种方案对比

单Reactor单线程:酒店前台接待和大厅服务都是同一个人
单Reactor多线程:一个酒店前台接待,多个大厅服务员
主从Reactor:多个酒店前台接待,多个大厅服务员

Reactor模式优点:
1、响应快
2、扩展性好,可以任意扩展SubReactor
3、复用性好,Reactor模型本身与具体的事件处理逻辑无关,具有很高的复用性

Netty终极图:
image.png