单服务器高性能模式: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上的读事件很 ...
随机推荐
- Vue3响应式编程三剑客:计算属性、方法与侦听器深度实战指南
在Vue3开发中,计算属性.方法和侦听器是处理数据逻辑的核心工具.它们各自有不同的作用和适用场景,合理使用这些工具可以显著提升代码的可读性和性能.本篇将深入探讨这三者的定义.使用场景以及实际案例,并通 ...
- QT5笔记: 26. 多窗体应用程序设计
- Hadoop - 两个Namenode都是standby状态怎么处理
在任意一个standby的NN节点执行 再次访问 ctos01:9870页面
- 记一次QT的QSS多个控件设置同一个样式的问题
文章目录 Qt样式表的格式问题 问题的引入 qss 选择器 问题所在 Reference Qt样式表的格式问题 问题的引入 最近在进行样式设计的时候,发现了一个问题,具体如下: 我是将所有样式写到.q ...
- Ubuntu下如何管理多个ssh密钥
Ubuntu下如何管理多个ssh密钥 前言 我一直在逃避这个问题,误以为我能够单纯地用一个 ssh 走天下. 好吧,现实是我不得不管理多个 ssh 做,那就写个博客总结一下吧. 查阅后发现前人已经 ...
- NumPy学习8
今天学习了NumPy统计函数 16,NumPy统计函数 numpy_test8.py : import numpy as np ''' 16,NumPy统计函数 NumPy 提供了许多统计功能的函数, ...
- Tomcat之——宕机自动重启和每日定时启动tomcat
在项目后期维护中会遇到这样的情况,tomcat在内存溢出的时候就出现死机的情况和遇到长时间不响应,需要人工手动关闭和重启服务,针对这样的突发情况,希望程序能自动处理问题而不需要人工关于,所以才有了目前 ...
- 【Azure Developer】分享两段Python代码处理表格(CSV格式)数据 : 根据每列的内容生成SQL语句
问题描述 在处理一个数据收集工作任务上,收集到的数据内容格式都不能直接对应到数据库中的表格内容. 比如: 第一种情况:服务名作为第一列内容,然后之后每一列为一个人名,1:代表此人拥有这个服务,0:代表 ...
- Windows Terminal
... Windows Terminal 安装 命令行接口 Windows Terminal 的命令行接口是 wt 因此我们可以在运行输入 wt 打开 Windows Terminal 也可以在资源管 ...
- udl(Universal Data Link)通用数据连接文件
新建文本文档 更改后缀名为.udl(注意小点) 然后打开运行 配置并测试 改回后缀名.txt(有个小点哦) 打开就是了