§1 简介
核心特征
Reactor 即反应堆模式,别称 分发者模式、通知者模式。
通常是对多路复用思想的实现
- 多个连接或请求可以同时阻塞在一个 Reactor 上
- Reactor 可以对阻塞在其上的多个连接或请求进行监听,连接和请求就绪时会产生对应的事件
- Reactor 可以监听到事件,并同步的将它们分发给对应的处理器处理
整体模型
关键对象
反应堆模式由两种关键对象,整体模型如下
- Reactor
- 独立线程,管理所有注册的客户端
- 监听客户端事件,客户端请求就绪时会生成对应事件,并被 Reactor 监听到
- 分发客户端事件,交由对应的 Handler 处理
- 独立线程,管理所有注册的客户端
- Handler
- 事件的执行器,即真正处理请求的部分
- 根据不同的线程模型,可以由不同数量的线程调度
- 执行器通常有多个,每个线程处理的执行器不一定是单个
应用
最经典应用于 NIO(Netty) 的多路复用实现中
在 redis 中的网络 IO 多路复用中的应用参考 基础 | NIO - [从 redis 深度理解多路复用]
核心优势
- 响应快,虽然 Reactor 本身是同步的,但是没有必然阻塞的情况
- 尽量避免线程通信问题
虽然会有多线程、线程池,但通常用来分块处理
因此线程间的通信、共享可以尽量避免 - 扩展性优秀
见 [§2 常见线程模型] 的演进 - 复用性强
Reactor 与业务本身无关,但只要符合相关模型,就可以处理各种业务
§2 常见线程模型
单 Reactor 单线程
Reactor 和 Handler 在同一个线程中,如下图所示
Handler 完整负责业务处理
优点
- 模型简单,实现方便
- 无进程、线程通信竞争问题,天然同步、有序
缺点
- 性能问题 (体现在 Handler)
单线程,不能利用多核优势
虽然通过 Reactor 解决了阻塞问题,高并发下容易形成性能瓶颈
因为单线程毕竟性能有限,一个 Handler 在处理业务时无法响应其他连接 - 可靠性问题
线程终止或死循环时,这个模型不可用
适用场景
- 客户端数量有限
- 业务处理简单快速
比如 O ( 1 ) O(1) O(1) 复杂度的业务 - 可靠性要求不高
单 Reactor 多线程
Reactor 和 Handler 在同一个线程中,如下图所示
Handler 只负责监听和响应事件,相当于 Controller
Handler 将事件委托给 Worker 线程池,线程池中的各个线程相当于原来的 Handler
worker 处理完业务后,结果交回给 Handler,由 Handler send 回 Client
优点
- 可以利用多核优势
缺点
- 性能问题 (体现在 Reactor)
因为 Reactor 需要处理所有事件的监听和响应,高并发下会出现性能瓶颈 - 带来线程通信、共享等问题
主从 Reactor 多线程
Reactor 进行主从 Reactor 的区分
- 主 Reactor 只负责处理 accept 事件,相当于一级就绪
- 从 Reactor 负责其他事件,相当于二级就绪
Handler 依然只负责监听和响应事件
最终由 worker 负责真正事件的处理,处理业务
worker 处理完业务后,结果交回给 Handler,由 Handler send 回 Client
优点
- 可以利用多核优势
- 主从 Reactor 职责明确
- 主 Reactor 只负责处理新连接
- 从 Reactor 只负责处理指定的业务(可以按不同从 Reactor 进行划分)
- 主从 Reactor 数据交互简单
缺点
- 编码难度高
- 带来线程通信、共享等问题