Reactor是一种设计模式,也叫做反应器模式或分发器模式。常用于处理并发网络IO请求场景下的一种设计模式,Reactor使用到了IO多路复用模型的机制,因此如果学习过NIO的话,会感觉非常熟悉

Reactor模式整体设计图:

整体设计概念图

Reactor模式中核心的组成

  • Reactor:Reactor在一个单独的线程中运行,负责监听和分发事件,分发给适当的处理程序(线程)来对IO事件做出反应。对应上图的ServiceHandler。它就像公司的电话接线员,它接听来自客户的电话并将线路转移到适当的联系人
  • Handler:处理程序执行IO事件要完成的实际事件。对应上图的EventHandler。Reactor通过调度适当的处理程序(线程)来响应IO事件,处理程序执行非阻塞操作。

根据Reator的数量和处理响应事假的线程数量不同,有三种典型的实现

单Reactor单线程

它与NIO多路复用模型非常的类似。Reactor与EventHandler在一个线程中。通过一个线程搞定所有的IO操作。

单Reactor单线程概念图

流程说明:

  1. select就是NIO复用模型中标准的网络编程API,可以实现应用程序通过一个阻塞对象监听多路连接请求
  2. Reactor对象通过select监听客户端请求事件,收到事件后通过Dispatch进行分发
  3. 如果是建立连接请求事件,Reactor会分发到Acceptor通过accept处理连接请求,然后创建一个Handler对象处理连接完成后的后续业务。
  4. 如果不是请求连接事件,则Reactor会分发调用连接对应的Handler来响应
  5. Handler会完成Read->业务处理->send的完整业务流程

优点:模型简单,没有多线程的竞争问题
缺点

  1. 只有一个线程对事件进行处理,完全无法发挥多核CPU的性能
  2. 可靠性低,当线程意外终止时,整个网络通信系统将不可用
  3. 并发性能低

这种实现方式,只适用于客户端数量有限,并且处理的业务非常快的场景下。

单Reactor多线程

这种实现方式,也只有一个Reactor,但是它有多个Handler进行事件的处理,并且引入了Worker线程池,线程池中的每一个线程都能进行相关业务的处理。在这种模式下,每个Handler只进行响应事件的处理,也就是读写操作。业务操作交给线程池中的线程来执行。

单Reactor多线程概念图

流程说明:

  1. Reactor对象通过select监听客户端请求事件,收到事件后通过Dispatch进行分发
  2. 如果是建立连接请求事件,Reactor会分发到Acceptor通过accept处理连接请求,然后创建一个Handler对象处理连接完成后的后续业务。
  3. 如果不是请求连接事件,则Reactor会分发调用连接对应的Handler来响应,但是这里的handler只负责响应事件,不进行具体的业务处理。也就是说,它读取到数据后,会把数据分发给后面的Worker线程池的某个线程进行业务处理。
  4. worker线程池会分配一个独立的线程完成业务,操作完后将数据返回给Handler
  5. Handler收到处理完的数据后再负责把数据发送出去

优点

  1. 使用了多个线程来进行业务的处理,充分的利用了多核CPU的处理能力
  2. 相比于单Reactor单线程,这种实现方式的并发性能得到了提高

缺点

  1. 使用了多线程提高了复杂度,需要考虑多线程的并发问题了
  2. 虽然使用了多线程进行业务的处理,但是请求的监听和分发还是单个Reactor在处理,这在高并发条件下也会存在瓶颈。
  3. 可靠性还不够好,如果Reactor出现问题,整个网络通信将不可用

主从Reactor多线程

针对于单Reactor多线程,Reactor在单线程中运行,高并发场景下很容易称为性能瓶颈,因此我们可以让Reactor在多线程下运行。
这种实现方式可以简单理解为:它在单Reactor多线程的基础之上对Reactor分了一个层,Reactor总体上分为Reactor主线程和子线程,使它们的分工更明确。Reactor主线程只负责监听客户端请求连接的事件。其他的连接事件由子线程负责监听处理。

注意:Reactor子线程可以有多个,主从Reactor多线程通过这种实现方式将客户端请求的事件分配给不同的Reactor来进行处理

主从Reactor多线程概念图

流程说明:

  1. Reactor主线程只监听请求连接事件并分发到Acceptor进行处理,创建出对应的连接后,它会把这个连接分配给多个Reactor子线程中的一个。
  2. Reactor子线程将该连接加入到连接队列进行监听。那么这个连接发送的事件将会被这个Reactor子线程进行监听并处理,后续的处理与单Reactor多线程的步骤相同。

优点

  1. 并发性能大大提升。可靠性也得到了增强
  2. Reactor主线程与子线程分工明确,主线程只负责接收新的连接,子线程负责完成建立连接后的事件处理

缺点:编程复杂度较高

Reactor的这种实现方式在许多项目中被广泛使用,包括Nginx、Netty等

总结

Reactor模式的这三种实现方式用生活的案例来理解:

  • 单Reactor单线程:就好比餐厅的前台接待员与服务员是同一个人,全程为顾客服务
  • 单Reactor多线程:1个前台接待员,多个服务员,接待员只负责接待
  • 主从Reactor多线程:多个前台接待员,多个服务员

Reactor模式的优点:

  • Reactor使用了IO多路复用模型的机制,因此多路复用模型的优点它都具有
  • Reactor的扩展性好,它可以方便的通过增加Reactor实例的个数来充分利用CPU资源
  • 复用性好,Reactor模型本身与具体的事件处理的逻辑无关,具有很高的复用性

补充:Netty就使用到了Reactor模式中的主从Reactor多线程的实现方式,并在此之上做了一定的改进。在Netty中,Reactor主线程也可以定义多个。在可靠性与并发效率上提升很大。

最后修改:2021 年 08 月 08 日 04 : 34 PM
如果觉得我的文章对你有用,请随意赞赏