单服务器高性能模式:Reactor 与Proactor
极客时间:《从 0 开始学架构》:单服务器高性能模式:Reactor 与Proactor
1、引言
单服务器高性能的 PPC 和 TPC 模式,它们的优点是实现简单,缺点是都无法支撑高并发的场景,尤其是互联网发展到现在,各种海量用户业务的出现,PPC 和 TPC 完全无能为力。本节讲述下应对高并发场景的单服务器高性能架构模式:Reactor 和 Proactor。
2、Reactor
PPC 模式最主要的问题就是每个连接都要创建进程(TPC线程类似),连接结束后进程就销毁了,造成了很大的浪费。因此,想到了资源复用,即创建一个线程池,将连接分配给进程,一个进程可以处理多个连接的业务。
引入资源池也会引入一个新的问题,进程如何高效的处理多个连接的业务?
处理流程:“read -> 业务处理 -> write”,当都有数据时,进程一个接一个的处理,但若当前连接没有数据时,read操作就阻塞到那了。最简单的方式就是将read操作改为非阻塞方式,然后进程不断地轮询多个连接。虽然能够粗暴的解决问题,但轮询除消耗CPU 不说,当一个进程处理多个连接时,轮询效率就会很低l。
很容易想到,只有当连接上有数据的时候进程才去处理,这就是 I/O 多路复用技术的来源。
I/O 多路复用技术归纳起来有两个关键实现点:
- 当多条连接共用一个阻塞对象后,进程只需要在一个阻塞对象上等待,而无须再轮询所有连接,常见的实现方式有 select、epoll、kqueue 等。
- 当某条连接有新的数据可以处理时,操作系统会通知进程,进程从阻塞状态返回,开始进行业务处理。
I/O 多路复用结合线程池,即:Reactor,中文是“反应堆”,是“事件反应”的意思,通俗来讲就是“来了一个事件我就有相应的反应”,“我”就是Reactor,具体的反应就是我们写的代码。Reactor 会根据事件类型来调用相应的代码进行处理。Reactor 模式也叫 Dispatcher 模式,I/O 多路复用统一监听事件,收到事件后分配(Dispatch)给某个进程。
Reactor 模式的核心组成部分包括 Reactor 和处理资源池(进程池或线程池),其中 Reactor 负责监听和分配事件,处理资源池负责处理事件。
最终 Reactor 模式有这三种典型的实现方案:
- 单 Reactor 单进程 / 线程。
- 单 Reactor 多线程。
- 多 Reactor 多进程 / 线程。
2.1、单 Reactor 单进程 / 线程
单 Reactor 单进程 / 线程的方案示意图如下(以进程为例):

注意,select、accept、read、send 是标准的网络编程 API,dispatch 和“业务处理”是需要完成的操作,其他方案示意图类似。
注解:
- Reactor 对象通过 select 监控连接事件,收到事件后通过 dispatch 进行分发。
- 如果是连接建立的事件,则由 Acceptor 处理,Acceptor 通过 accept 接受连接,并创建一个 Handler 来处理连接后续的各种事件。
- 如果不是连接建立事件,则 Reactor 会调用连接对应的 Handler(第 2 步中创建的 Handler)来进行响应。
- Handler 会完成 read-> 业务处理 ->send 的完整业务流程。
优点:
- 简单,没有进程间通信,没有进程竞争,全部都在同一个进程内完成。
缺点:
- 只有一个进程,无法发挥多核 CPU 的性能;只能采取部署多个系统来利用多核 CPU,但这样会带来运维复杂度,本来只要维护一个系统,用这种方式需要在一台机器上维护多套系统。
- Handler 在处理某个连接上的业务时,整个进程无法处理其他连接的事件,很容易导致性能瓶颈。
因此,该方案只适用于业务处理非常快速的场景,目前比较著名的开源软件中使用单 Reactor 单进程的是 Redis。
2.2. 单 Reactor 多线程
单 Reactor 多线程方案示意图是:

注解:
- 主线程中,Reactor 对象通过 select 监控连接事件,收到事件后通过 dispatch 进行分发。
- 如果是连接建立的事件,则由 Acceptor 处理,Acceptor 通过 accept 接受连接,并创建一个 Handler 来处理连接后续的各种事件。
- 如果不是连接建立事件,则 Reactor 会调用连接对应的 Handler(第 2 步中创建的 Handler)来进行响应。
- Handler 只负责响应事件,不进行业务处理;Handler 通过 read 读取到数据后,会发给 Processor 进行业务处理。
- Processor 会在独立的子线程中完成真正的业务处理,然后将响应结果发给主进程的 Handler 处理;Handler 收到响应后通过 send 将响应结果返回给 client。
优点:
能够充分利用多核多 CPU 的处理能力
缺点:
多线程数据共享和访问比较复杂
Reactor 承担所有事件的监听和响应,只在主线程中运行,瞬间高并发时会成为性能瓶颈。
3.3、多 Reactor 多进程 / 线程
多 Reactor 多进程 / 线程方案示意图是(以进程为例):

方案详细说明如下:
- 父进程中 mainReactor 对象通过 select 监控连接建立事件,收到事件后通过 Acceptor 接收,将新的连接分配给某个子进程。
- 子进程的 subReactor 将 mainReactor 分配的连接加入连接队列进行监听,并创建一个 Handler 用于处理连接的各种事件。
- 当有新的事件发生时,subReactor 会调用连接对应的 Handler(即第 2 步中创建的 Handler)来进行响应。
- Handler 完成 read→业务处理→send 的完整业务流程。
多 Reactor 多进程 / 线程的方案看起来比单 Reactor 多线程要复杂,但实际实现时反而更加简单,主要原因是:
- 父进程和子进程的职责非常明确,父进程只负责接收新连接,子进程负责完成后续的业务处理。
- 父进程和子进程的交互很简单,父进程只需要把新连接传给子进程,子进程无须返回数据。
- 子进程之间是互相独立的,无须同步共享之类的处理(这里仅限于网络模型相关的 select、read、send 等无须同步共享,“业务处理”还是有可能需要同步共享的)。
3、Proactor
Reactor 是非阻塞同步网络模型,因为真正的 read 和 send 操作都需要用户进程同步操作。这里的“同步”指用户进程在执行 read 和 send 这类 I/O 操作的时候是同步的,如果把 I/O 操作改为异步就能够进一步提升性能,这就是异步网络模型 Proactor。
Proactor 中文翻译为“前摄器”,Reactor 可以理解为“来了事件我通知你,你来处理”,而 Proactor 可以理解为“来了事件我来处理,处理完了我通知你”。这里的“我”就是操作系统内核,“事件”就是有新连接、有数据可读、有数据可写的这些 I/O 事件,“你”就是我们的程序代码。

- Proactor Initiator 负责创建 Proactor 和 Handler,并将 Proactor 和 Handler 都通过 Asynchronous Operation Processor 注册到内核。
- Asynchronous Operation Processor 负责处理注册请求,并完成 I/O 操作。
- Asynchronous Operation Processor 完成 I/O 操作后通知 Proactor。
- Proactor 根据不同的事件类型回调不同的 Handler 进行业务处理。
- Handler 完成业务处理,Handler 也可以注册新的 Handler 到内核进程。
理论上 Proactor 比 Reactor 效率要高一些,异步 I/O 能够充分利用 DMA 特性,让 I/O 操作与计算重叠,但要实现真正的异步 I/O,操作系统需要做大量的工作。目前 Windows 下通过 IOCP 实现了真正的异步 I/O,而在 Linux 系统下的 AIO 并不完善,因此在 Linux 下实现高并发网络编程时都是以 Reactor 模式为主。
单服务器高性能模式:Reactor 与Proactor的更多相关文章
- 高性能IO设计的Reactor和Proactor模式(转)
在高性能的I/O设计中,有两个比较著名的模式Reactor和Proactor模式,其中Reactor模式用于同步I/O,而Proactor运用于异步I/O操作. 在比较这两个模式之前,我们首先的搞明白 ...
- Reactor和Proactor模式
在高性能的I/O设计中,有两个比较著名的模式Reactor和Proactor模式,其中Reactor模式用于同步I/O,而Proactor运用于异步I/O操作.同步和异步 同步和异步是针对应用程序和内 ...
- Reactor和Proactor模式的讲解(关于异步,同步,阻塞与非阻塞)
在高性能的I/O设计中,有两个比较著名的模式Reactor和Proactor模式,其中Reactor模式用于同步I/O,而Proactor运用于异步I/O操作. 在比较这两个模式之前,我们首先的搞明白 ...
- actor、reactor与proactor模型:高性能服务器的几种模型概念(转)
actor模型: 实体之通过消息通讯,各自处理自己的数据,能够实现这并行. 说白了,有点像rpc. skynet是actor模型. reactor模型: 1 向事件分发器注册事件回调 2 事件发生 4 ...
- 【转载】高性能I/O设计模式Reactor和Proactor
转载自:http://blog.csdn.net/roger_77/article/details/1555170 昨天购买了<程序员>杂志 2007.4期,第一时间去翻阅了一遍,其中有一 ...
- 两种高性能 I/O 设计模式 Reactor 和 Proactor
两种高性能 I/O 设计模式 Reactor 和 Proactor Reactor 和 Proactor 是基于事件驱动,在网络编程中经常用到两种设计模式. 曾经在一个项目中用到了网络库 libeve ...
- I/O模型系列之四:两种高性能IO设计模式 Reactor 和 Proactor
不同的操作系统实现的io策略可能不一样,即使是同一个操作系统也可能存在多重io策略,常见如linux上的select,poll,epoll,面对这么多不同类型的io接口,这里需要一层抽象api来完成, ...
- I/O模型之三:两种高性能 I/O 设计模式 Reactor 和 Proactor
目录: <I/O模型之一:Unix的五种I/O模型> <I/O模型之二:Linux IO模式及 select.poll.epoll详解> <I/O模型之三:两种高性能 I ...
- 【转】Reactor与Proactor两种模式区别
转自:http://www.cnblogs.com/cbscan/articles/2107494.html 两种IO多路复用方案:Reactor and Proactor 一般情况下,I/O 复用机 ...
- ACE_linux:Reactor与Proactor两种模式的区别
一.概念: Reactor与Proactor两种模式的区别.这里我们只关注read操作,因为write操作也是差不多的.下面是Reactor的做法: 某个事件处理器宣称它对某个socket上的读事件很 ...
随机推荐
- 面试官:你是如何进行SQL调优的?
SQL调优是我们后端开发人员面试中的高频考点,也是实际工作中提升数据库性能的关键技能.面对"你是如何进行SQL调优的?"这个问题,你是否能条理清晰地分析问题并提供解决方案? 1. ...
- Flink - [08] 状态一致性
题记部分 一.什么是状态一致性 有状态的流处理,内部每个算子任务都可以有自己的状态.对于流处理器内部来说,所谓的状态一致性,其实就是我们所说的计算结果要保证准确.一条数据也不应该丢失,也不应该重复 ...
- Hadoop - HDFS 概述
什么是HDFS HDFS的优缺点 HDFS的文件块大小 HDFS的写数据流程 HDFS的副本配置策略 HDFS读数据的流程 什么是HDFS HDFS(Hadoop Distributed File S ...
- HTTP协议与RESTful API实战手册(二):用披萨店故事说透API设计奥秘 🍕
title: HTTP协议与RESTful API实战手册(二):用披萨店故事说透API设计奥秘 date: 2025/2/27 updated: 2025/2/27 author: cmdragon ...
- Elasticsearch搜索引擎学习笔记(一)
核心概念 ES -> 数据库 索引index -> 表 文档 document -> 行(记录) 字段 fields -> 列 安装Elasticsearch 1. 上传后解压 ...
- 在ubuntu系统下,安装opencv各个版本
要在Linux系统上安装OpenCV库,你可以通过包管理器(如apt)来安装.以下是详细的步骤,包括如何在/usr/local/lib或/usr/lib/x86_64-linux-gnu目录下安装Op ...
- python excel 数据整理:如何删除重复的记录
data = frame.drop_duplicates(subset='', keep='first', inplace='') drop_duplicates用法:subset='需要去重复的列名 ...
- TypeScript 为什么使用 Go 而不是 Rust 重写 ?官方回应来了
TypeScript官推最近宣布他们正在移植到 Go,速度已经提高了 10 倍之多. 作为以性能为代表的另一语言Rust,人们自然会疑惑为什么没有选Rust语言重构呢?为方便大家快速理解,我用Deep ...
- vscode如何退出/切换 github 账号
退出/切换 github 账号 左下角点击头像按钮,选择注销,然后再重新登录
- MySQL 是否可以用 Docker 容器化?
容器 容器是为了解决 "在切换运行环境时,如何保证软件能够正常运行",容器是轻量级应用代码包,它包含在任何环境中运行所需的所有元素的软件包.容器可以虚拟化操作系统,包含依赖项,例如 ...