首页 > 其他分享 >高性能的Reactor和Proactor模式学习

高性能的Reactor和Proactor模式学习

时间:2024-11-07 18:09:38浏览次数:4  
标签:异步 Reactor 进程 高性能 线程 事件 Proactor

0、引言

在上一篇的笔记中,我们学习了操作系统提供的高效I/O管理技术,主要用于解决服务器在高并发场景下的资源浪费和瓶颈问题。但是在实际的代码编写中,要是我们都全部调用底层的I/O多路复用接口来编写网络程序这种面向过程的方式,必然会导致开发的效率不高。于是在这一章节,我们来学习两个重要的Reactor和Proactor模型,他们都借用了I/O多路复用机制来高效地管理和分发事件,并且更利于程序员进行程序开发的代码编写。

1、Reactor和Proactor

基于面向对象的思想,大佬们对I/O多路复用作了一层封装,让使用者不用考虑底层网络接口的细节,只需要关注应用代码的编写。

大佬们为这个模式取名为:Reactor模式,翻译过来的意思为「反应堆」,这个反应堆指的是「对事件反应」,也就是说来一个事件,Reactor就有相对应的反应/响应。

Reactor模式也叫Dispatcher模式,即I/O多路复用监听事件,收到事件后,根据事件类型分配(Dispatch)给某个进程/线程。

Reactor模式主要由Reactor和处理资源池这两个核心部分组成,它们所负责的事情如下:

  • Reactor负责监听和分发事件,事件类型包含连接事件、读写事件;
  • 处理资源池负责处理事件,如read->业务逻辑->send;

(说到这里,我觉得就像是使用go的gin框架编写web程序时,需要在router配置路由一样,这就对应了Reactor的监听事件,但是具体的处理流程就交给handler来处理一样,这种思想具有相似性正是因为这种设计思想在面对复杂逻辑的时候具有更高效的并发处理效率。)

Reactor模式是灵活多变的,在理论上该模式有4种方案的选择:

  • 单Reactor单进程/线程;
  • 单Reactor多进程/线程;
  • 多Reactor单进程/线程;
  • 多Reactor多进程/线程;

其中,「多Reactor单进程/线程」实现方案相比与「单Reactor单进程/线程」方案,不仅复杂而且没有性能优势,在实际中没有应用。

省下的3个方案都是比较经典主流的。

方案具体使用进程还是线程,要看使用的编程语言以及平台有关:

  • Java语言一般使用线程,比如Netty
  • C语言进程和线程都可以,例如Nginx使用的是进程,Memcache使用的是线程。

2、Reactor

2.1、单Reactor单进程/线程

下面是一张「单Reactor单进程」的方案示意图

进程中有Reactor、Acceptor、Handler三个对象:

  • Reactor对象的作用是监听和事件分发;
  • Acceptor对象的作用是获取连接;
  • Handler对象的作用是处理业务;

这里的select、accept、read、send是系统调用函数,dispatch和「业务处理」是需要完成的操作,其中dispatch是分发事件操作。

该方案的流程如下:

  • Reactor对象通过select(IO多路复用接口)监听事件,收到事件后通过dispatch进行分发;
  • 如果是连接建立事件,则被分发到Acceptor对象进行处理,该对象会调用accept获取连接并创建一个handler对象来处理后续的响应。
  • 如果不是,则交由Handler对象响应。
  • handler对象通过read->业务处理->send的流程来完成完整的业务流程。

该方案有两个缺点:

  • 第一个缺点,因为只有一个进程,无法利用多核CPU的性能;
  • 第二个缺点,Handler对象在业务处理时,整个进程无法处理其他连接的事件,如果业务处理耗时过长,那么造成响应的延迟就会更长;

所以单Reactor单进程的方案不适合计算机密集型的场景,只适用于业务处理非常快速的场景。

Redis是由C语言实现的,在6.0版本之间采用的就是这种方案。

2.2、单Reactor多进程/线程

为了弥补单进程/线程的缺点,于是引入了多进程/线程。

我们来看它的不同之处:

  • Handler不再去处理具体的业务逻辑,而是只负责数据的接收和发送。
  • 具体的业务逻辑通过分配一个字线程Processor去完成,将处理结果返回给Handler对象。

这种方案的优势在于能够充分利用多核CPU的性能,但是引入了多线程就自然带来了线程竞争资源的问题。

我们需要使用互斥锁来保证对共享资源的并发访问问题。

单Reactor模式还有个问题,因为一个Reactor对象承担所有事件的监听和响应,而且只在主线程中运行,在面对瞬间高并发的场景时,容易成为性能的瓶颈的地方。

2.3、多Reactor多进程/线程

为了能够面对瞬间高并发的场景,于是进而引用多Reactor。

它的方案大致步骤是:主线程的MainReactor对象通过select监控连接建立事件,收到事件后通过Acceptor对象获取连接,此时子Reactor会将MainReactor建立的连接加入进select继续监听,在今后的事件发生中,转而调用SubReactor对应的Handler对象来响应。

这种方案实现起来更加的简单:

  • 主线程和子线程分工明确,主线程只负责接收新连接,子线程负责完成后续的业务处理。
  • 主线程和子线程的交互简单,只需要把连接传递给子线程,无需等待返回数据。

3、Proactor

Reactor是非阻塞同步网络模式,而Proactor是异步网络模式

在非阻塞I/O中,read请求在数据未准备完善的时候立刻返回,可以继续往下执行,此时进程不断地轮询内核,直到数据准备好后,内核将数据拷贝到用户缓存区,read调用才可以获取到结果,过程如下:

需要注意的是,这里的最后一次read调用中,等待数据从内核缓冲区拷贝到用户缓冲区的过程是需要等待的,也就是说这个步骤是「同步的」。

因此,无论read和send是阻塞I/O还是非阻塞I/O,都是同步调用。如果内核实现的拷贝效率不高,read调用就会在这个同步过程中等待比较长的时间。

而真正的异步I/O是「内核数据准备好」和「数据从内核态拷贝到用户态」这两个过程都不需要等待。

当我们发起aio_read(异步I/O)之后,就立即返回,内核自动将数据从内核空间拷贝到用户空间,这个拷贝过程同样是异步的,应用程序并不需要主动发起拷贝动作

显而易见的是,异步I/O比同步I/O的性能更好。

Proatcor正是采用了异步I/O技术,所以被称为异步网络模型。

我们再来对比一下Reactor和Proactor的区别:

  • Reactor是非阻塞同步网络模式,感知的是就绪可读写事件。在每次感知到有事件发生的时候,就需要应用程序主动调用read方法来完成数据的读取,这个过程是同步的,读取完数据后应用进程才能处理数据。
  • Proactor是异步网络模式,感知的是已完成的读写事件。在发起异步读写请求时,需要传入数据缓冲区的地址等信息,系统内核就可以自动帮我们将数据的读写请求工作完成,操作系统完成读写工作后,就会自动通知应用进程直接处理数据。

因此,Reactor可以理解为「来了事件操作系统通知应用进程,让应用进程来处理」,而Proactor可以理解为「来了事件操作系统来处理,处理完再通知应用进程」。

无论是Reactor还是Proactor,都是基于一种「事件分发」的网络编程模式,区别在于Reactor模式是基于「待完成」的I/O事件,而Proactor模式则是基于「已完成」的I/O事件

Proactor的示意图如下:

Proactor工作流程如下:

  • Proactor Initiator负责创建Proactor和Handler对象,并将Proactor和Handler通过Asychronous Operation Processor注册到内核
  • Asychronous Operation Processor负责处理注册请求,并处理I/O操作
  • Asychronous Operation Processor完成I/O操作后通知Proactor
  • Proactor回调对应的Handler进行业务处理
  • Handler完成业务处理

可惜的是,在Linux下的异步I/O是不完善的,aio系列函数是由POSIX定义的异步操作接口,不是真正的操作系统级别的支持,而是在用户空间模拟出来的异步,并且仅支持基于本地文件的aio异步操作,网络编程中的socket是不支持的,这也使得Linux的高性能网络程序都是使用Reactor方案。

Windows里实现了一套完整的支持socket的异步编程接口,叫做IOCP。由操作系统级别实现的异步I/O,是真正意义上的异步I/O。

4、总结

常见的Reactor实现方案有三中。

第一种是单Reactor单进程/线程,不考虑进程间通信以及数据同步的问题,实现起来简单,但是无法利用多核CPU,而且处理业务逻辑的时间不能太长,所以只适用于业务处理快速的场景,Redis的6.0版本之前采用的是单Reactor单进程的方案。(6.0版本之后是单线程执行 + 多线程 I/O 优化的改进型 Reactor 模型)

第二种方案单Reactor多进程/线程,解决了方案一的缺陷,但是在面对瞬时高并发的场景时,单Reactor会成为性能瓶颈。

第三种方案是多Reactor多进程/线程,主Reactor只负责监听事件,响应事件的工作交给了Reactor,Netty和Memcache都采用了「多Reactor多线程」的方案,Nigin采用了这种模式。

Reactor可以理解为「来了事件操作系统通知应用进程,让应用进程来处理」,而Proactor为「来了事件操作系统来处理,处理完通知进程」。

无论是Proactor还是Reactor,都是一种基于「事件分发」的网络编程模式。

5、参考博客

本篇博客个人学习、总结、摘抄至:[小林coding](9.3 高性能网络模式:Reactor 和 Proactor | 小林coding)

标签:异步,Reactor,进程,高性能,线程,事件,Proactor
From: https://www.cnblogs.com/MelonTe/p/18533718

相关文章

  • .NET 8 高性能跨平台图像处理库 ImageSharp
    阅读目录前言项目介绍项目使用常用方法常用滤镜项目地址总结最后前言传统的System.Drawing库功能丰富,但存在平台限制,不适用于跨平台开发。.NET8的发布,ImageSharp成为了一个更好的选择。ImageSharp是一个完全开源、高性能且跨平台的图像处理库,专为.NET设计......
  • .NET 8 高性能跨平台图像处理库 ImageSharp
    合集-.NET开源项目(27) 1.推荐一款界面优雅、功能强大的.NET+Vue权限管理系统08-052..NET开源权限认证项目MiniAuth上线08-063..NET与LayUI实现高效敏捷开发框架08-084..NET8+Blazor多租户、模块化、DDD框架、开箱即用08-095.推荐一个优秀的.NETMAUI组件......
  • RK3588嵌入式主板赋能无人机,开启高性能航拍新时代
    随着科技的飞速发展,无人机(UAV)作为现代科技的重要成果,已经从最初的军事领域逐步渗透到民用市场的各个角落。从热门的电子消费品到影视拍摄的得力助手,再到灾害救援、环保检测、电力巡检及农业生产等多领域的关键工具,无人机的应用领域日益广泛,市场需求也持续攀升。特别是在追求智......
  • 2024年云手机推荐榜单:高性能云手机推荐
    无论是手游玩家、APP测试人员,还是数字营销工作者,云手机都为他们带来了极大的便利。本文将为大家推荐几款在市场上表现优异的云手机,希望这篇推荐指南可以帮助大家找到最适合自己的云手机!1.OgPhone云手机OgPhone云手机是一款备受海外推广与矩阵运营使用者好评的神器,它在海外......
  • 程序员推荐的笔记本,2024年六款高性能笔记本电脑推荐!非常适合计算机专业,做编程设计的程
    文|二加一网络科技对于计算机相关专业,尤其是学习编程或程序员来说,选择一款高性能的笔记本电脑至关重要,它不仅能够提供流畅稳定的编程环境,还能助力高效地完成各项工作。接下来,小编就来推荐六款2024年非常适合编程的高性能笔记本电脑,看看哪一款能够成为你的得力助手。第......
  • 用超高纯度的正弦波振荡器测试18位ADC:精确度量,保障高性能
    在现代电子工程中,高分辨率模数转换器(ADC)的精度和性能是决定系统整体表现的关键因素之一。尤其对于需要极高数据精度和动态范围的应用,如高精度测量、音频处理、无线通信及科学仪器等领域,18位ADC更是不可或缺。然而,要准确评估这些高性能ADC的保真度,就需要采用一种高灵敏度的测试方......
  • 国产化基于 Zynq-7100 的高性能计算模块FMC载板
    国产化基于Zynq-7100的高性能计算模块FMC载板是一款高性能计算模块。主控芯片采用Xilinx公司Zynq-7系列SoC家族中的XC7Z100-2FFG900(兼容XC7Z045-2FFG900,国产FMQL45T900,和XC7Z035-2FFG900)。其内含ARM公司的Cortex-A9MPCore处理器系统与Xilinx的K......
  • 编写高性能爬虫抓取股票行情数据
    最近给一个私募大佬帮忙做了一些股票交易有关的系统,其中涉及到行情数据抓取的问题,一番摸索之后,把成果在这里做个分享。我把行情抓取的部分,和一个写手记的小功能,单独拿了出来放在一个小系统里面,可以免费使用:https://rich.shengxunwei.com/先简单介绍下这个小系统的样子,然后我会详......
  • 基于SpringBoot + Vue的高性能集群共享平台(角色:用户、教师、管理员)
    文章目录前言一、详细操作演示视频二、具体实现截图三、技术栈1.前端-Vue.js2.后端-SpringBoot3.数据库-MySQL4.系统架构-B/S四、系统测试1.系统测试概述2.系统功能测试3.系统测试结论五、项目代码参考六、数据库代码参考七、项目论文示例结语前言......
  • 基于ZU11EG或者ZU19EG的高性能双FMC 光纤PCIE载板
       基于ZU11EG或者ZU19EG的高性能双FMC光纤PCIE载板是一款高性能的FMC/FMC+载板。板载1个HPC形式的FMC连接器和1个HSPC形式的FMC+连接器。板卡选用了1片ZynqUltraScale+MPSoC家族的XCZU19EG-2FFVC1760芯片作为主控。其PS和PL各搭配1组9颗8bit1G......