要点

  1. 事件驱动
  2. 可以处理一个或多个输入源
  3. 通过多路复用将请求的事件分发给对应的处理器处理

Reacotr 模型主要分为三个角色

  1. Reactor:把IO事件分配给对应的handler处理;
  2. Acceptor:处理客户端连接事件;
  3. Handler:处理非阻塞的任务;

Reactor 线程模型分类

根据 Reactor 的数量和处理资源的线程数量的不同,分为三类:

  1. 单Reactor单线程模型
  2. 单Reactor多线程模型
  3. 多Reactor多线程模型

单 Reactor 单线程模型

这种模型在Reactor中处理事件,并分发事件,如果是连接事件交给acceptor处理,如果是读写事件和业务处理就交给handler处理,但始终只有一个线程执行所有的事情

图片

该线程模型的不足

  1. 仅用一个线程处理请求,对于多核资源机器来说是有点浪费的
  2. 当处理读写任务的线程负载过高后,处理速度下降,事件会堆积,严重的会超时,可能导致客户端重新发送请求,性能越来越差
  3. 单线程也会有可靠性的问题

单 Reactor 多线程模型

这种模型和第一种模型到的主要区别是把业务处理从之前的单一线程脱离出来,换成线程池处理,也就是 Reactor 线程只处理连接事件和读写事件,业务处理交给线程池处理,充分利用多核机器的资源、提高性能并且增加可靠性。
image-20230806185833236

单 Reactor 多线程模型

在 Reactor 单线程模型中,操作在同一个 Reactor 线程中完成。根据事件的不同类型,由 Dispatcher 将事件转发到不同的角色中处理。==连接事件转发到 Acceptor 处理、读写事件转发到不同的 Handler 处理==。

image-20230806190012772

多 Reactor 多线程模型

这种模型下和第二种模型相比是把Reactor线程拆分了mainReactor和subReactor两个部分,mainReactor只处理连接事件,读写事件交给subReactor来处理。业务逻辑还是由线程池来处理

mainRactor 只处理连接事件,用一个线程来处理就好(如果连接压力过大也可以进化为线程池处理)。处理读写事件的 subReactor 个数一般和 CPU 数量相等,一个 subReactor 对应一个线程,业务逻辑由线程池处理。相当于是保证了可用性,即使某个 SubReactor 异常了,也可以由其他 SubReactor 继续运行。

这种模型使各个模块职责单一,降低耦合度,性能和稳定性都有提高。
这种模型在许多项目中广泛应用,比如 Netty 的==主从线程模型==等(每个 NIOEventLoop 就是一个 Reactor 线程)。