概念:
Reactor 模式也叫 Dispatcher 模式(在很多开源的系统里面会看到这个名称的类,其实就是实现 Reactor 模式的),更加贴近模式本身的含义,即 I/O 多路复用统一监听事件,收到事件后分配(Dispatch)给某个进程。
组成:
Reactor 模式的核心组成部分包括 Reactor 和处理资源池(进程池或线程池),其中 Reactor 负责监听和分配事件,处理资源池负责处理事件。
初看 Reactor 的实现是比较简单的,但实际上结合不同的业务场景,Reactor 模式的具体实现方案灵活多变,主要体现在:Reactor 的数量可以变化:可以是一个 Reactor,也可以是多个 Reactor。资源池的数量可以变化:以进程为例,可以是单个进程,也可以是多个进程(线程类似)。将上面两个因素排列组合一下,理论上可以有 4 种选择,但由于“多 Reactor 单进程”实现方案相比“单 Reactor 单进程”方案,既复杂又没有性能优势,因此“多 Reactor 单进程”方案仅仅是一个理论上的方案,实际没有应用。最终
最终实现方式:
Reactor 模式有这三种典型的实现方案:
单 Reactor 单进程 / 线程。
单 Reactor 多线程。
多 Reactor 多进程 / 线程。
以上方案具体选择进程还是线程,更多地是和编程语言及平台相关。例如,Java 语言一般使用线程(例如,Netty),C 语言使用进程和线程都可以。例如,Nginx 使用进程,Memcache 使用线程。
总结:
线程:java、netty、memcache
进程:redis、ngnix
memcache/netty:都是多reactor多线程
redis:单reactor单进程
Nginx: 多 Reactor 多进程
单reactor单进程:单reactor多线程:
多reactor多进程:
Proactor
Reactor 是非阻塞同步网络模型,因为真正的 read 和 send 操作都需要用户进程同步操作。这里的“同步”指用户进程在执行 read 和 send 这类 I/O 操作的时候是同步的,如果把 I/O 操作改为异步就能够进一步提升性能,这就是异步网络模型 Proactor。
理论上 Proactor 比 Reactor 效率要高一些,异步 I/O 能够充分利用 DMA 特性,让 I/O 操作与计算重叠,但要实现真正的异步 I/O,操作系统需要做大量的工作。目前 Windows 下通过 IOCP 实现了真正的异步 I/O,而在 Linux 系统下的 AIO 并不完善,因此在 Linux 下实现高并发网络编程时都是以 Reactor 模式为主。所以即使 Boost.Asio 号称实现了 Proactor 模型,其实它在 Windows 下采用 IOCP,而在 Linux 下是用 Reactor 模式(采用 epoll)模拟出来的异步模型。
内容补充
IO操作分两个阶段
1、等待数据准备好(读到内核缓存)
2、将数据从内核读到用户空间(进程空间)
一般来说1花费的时间远远大于2。
1上阻塞2上也阻塞的是同步阻塞IO
1上非阻塞2阻塞的是同步非阻塞IO,这讲说的Reactor就是这种模型
1上非阻塞2上非阻塞是异步非阻塞IO,这讲说的Proactor模型就是这种模型