首页 > 其他分享 >高性能网络通信模型——Reactor 和 Proactor

高性能网络通信模型——Reactor 和 Proactor

时间:2023-09-03 16:33:52浏览次数:45  
标签:网络通信 Reactor 模型 Handler 线程 事件 Proactor

原来 8 张图,就能学废 Reactor 和 Proactor (qq.com)

高并发编程--Reactor模式与Proactor模式 (qq.com)

image-20230903120136559

Reactor模型

Reactor,翻译为反应器,他是一个被动的感觉,可以理解为接收到客户端事件后,Reactor模型会根据事件类型调用相应的代码进行处理。Reactor模型也叫作Dispatcher模式,底层是I/O多路复用结合线程池

主要用于服务器端处理高并发网络IO请求,Reactor模型的核心思想可以总结成两个“3种”:

  • 三种事件——连接事件、读事件、写事件
  • 三种角色——reactor、acceptor、handler

事件

  • 客户端向服务器端发送连接请求,该请求对应了服务器的一个连接事件
  • 连接建立后,客户端给服务器端发送写请求,服务器端收到请求,需要从请求中读取内容,这就对应了服务器端读事件
  • 服务器经过处理后,把结果值返回给客户端,这就对应了服务器的写事件

image-20230903150731770

角色

上述描述了Reactor的事件,每个时间都需要有一个专门的负责人,在Reactor模型中,这个负责人就是角色,其说明如下:

  • 连接事件acceptor来处理,只负责接收连接;acceptor在接受连接后,会创建handler用于后续读写事件的处理
  • 读写事件handler处理,处理完后响应客户端
  • 在连接事件、读写事件同时发生的高并发场景中,需要Reactor角色专门监听和分配事件:连接事件给acceptor,读写事件给handler。

Reactor线程模型

Reactor 线程模型有「单 Reactor 单线程模型」、「单 Reactor 多线程模型」、「多 Reactor 多线程模型」 三种。

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

至于是线程还是进程,Java 语言一般使用线程

1 单Reactor单线程模型

单 Reactor 单线程模型,很容易理解:接受请求、业务处理、响应请求都在一个线程中处理。

图片

工作原理

  1. Reactor通过监听select函数监听事件,受到事件后通过dispatch分发给acceptor或handler;
  2. 如果监听到客户端的连接事件,则分发给acceptor处理,acceptor通过accept接受连接,并创建一个handler事件来处理后续的各种事件;
  3. 如果不是连接建立事件,则reactor会调用连接对应的handler(在步骤2创建的handler)来进行响应
  4. handler通过:read -> 业务处理 -> send流程完成完整业务流程

优缺点

  • 优点是简单,不存在线程竞争,
  • 缺点是无法充分利用和发挥多核CPU的性能,当业务耗时很长时,容易造成阻塞

案例

  • Redis 6.0以下的版本使用的是「单 Reactor 单线程模型」,因为 Redis使用的是内存,CPU不是性能瓶颈,所以单 Reactor 单线程模型可以支持 Redis 单机服务的高性能
  • Netty4 通过参数配置,可以使用单 Reactor 单线程模型;

2 单Reactor多线程模型

鉴于单 Reactor 单线程模式无法充分利用和发挥多核 CPU 的性能,于是就诞生了单 Reactor 多线程模型。

图片

工作原理

  1. 在主线程中,Reactor 对象通过 select 监控事件,收到事件后通过 dispatch 分发给 Acceptor 或 Handler;
  2. 如果监听到 client 的连接事件,则分发给 Acceptor 处理,Acceptor 通过 accept 接受连接,并创建一个 Handler 来处理连接后续的各种事件;
  3. 如果不是连接建立事件,则 Reactor 会调用连接对应的 Handler(步骤2创建的 Handler)来进行响应。注意,此模型的 Handler 只负责响应事件,不进行业务处理;
  4. Handler 通过 read 读取到数据后,会发给 Processor 进行业务处理;
  5. Processor 会在独立的子线程中完成真正的业务处理,然后将响应结果发给主线程的 Handler 处理;Handler 收到响应后通过 send 将响应结果返回给 client;

优点

采用了线程池来处理业务逻辑,能够充分利用多 CPU 的处理能力

缺点

  1. 多线程数据共享和访问比较复杂。例如,子线程完成业务处理后,要把结果传递给主线程的 Reactor 进行发送,这里涉及共享数据的互斥和保护机制;
  2. 尽管引进了多线程处理业务逻辑,但是事件的监听和响应还是需要 Reactor 来处理,因此,瞬间高并发可能会造成 Reactor 的性能瓶颈;

案例

  • Netty4 通过参数配置,可以使用单 Reactor 多线程模型;

3 多Reactor多线程模型

单 Reactor 多线程模型的性能瓶颈在于单个 Reactor 的处理能力,于是我们很自然的想到:能不能增加多个 Reactor来提升性能?于是,多 Reactor 多线程模型就应孕而生。

图片

工作原理

  1. 父线程中 mainReactor 对象通过 select 监控连接建立事件,收到事件后通过 Acceptor 接收,将新的连接分配给某个子线程;
  2. 子线程的 subReactor 把 mainReactor 分配的连接加入到连接队列中并进行监听,同时创建一个 Handler 用于处理连接的各种事件;
  3. 当有新的事件发生时,subReactor 会调用连接对应的 Handler(步骤2创建的 Handler)来进行响应;
  4. Handler 通过:read-> 业务处理 ->send 流程完成完整业务流程;

优点

  • 父线程和子线程的职责明确,父线程只负责接收新连接,子线程负责完成后续的业务处理;
  • 父线程和子线程的交互简单,父线程只需要把新连接传给子线程,子线程无须返回数据;

案例

  • Nginx 采用的是多 Reactor 多进程模型,但方案与标准的多 Reactor 多进程有差异;

  • 开源软件 Memcache 采用的是多 Reactor 多线程模型;

  • Netty4 通过参数参数配置可以使用多 Reactor 多线程模型;

到此, Reactor模型就分析完了,需要说明的是:上文讲述的 Reactor 3种线程模型,同样可以以进程的方式部署,可能在逻辑处理上和线程有些差异。

接下来再分析和 Reactor模型很类似的 Proactor 模型

Proactor 模型

Proactor,中文翻译为”前摄器”,乍一看,这个翻译还是挺懵圈的,个人觉得”主动器”更符合 Proactor 模型的本意。Proactor 可以理解为“当有连接、读写等IO事件时,操作系统内核在处理完事件后主动通知我们的程序代码”。

可以理解为actor Pro Plus Ultra

图片

工作原理

  • 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 在处理高耗时 IO 时的性能要高于 Reactor,但对于低耗时 IO 的执行效率提升并不明显;
  • Proactor 的异步性使其并发处理能力要强于 Reactor;
  • Proactor 的实现逻辑复杂,编码成本较 Reactor 要高很多;
  • Proactor 的异步高度依赖于操作系统对于异步的支持。若操作系统对异步的支持不好,Proactor 的性能还不如 Reactor;

案例

  • Netty5, 它是采用 AIO,其网络通信模型就是 Proactor,但该版本已经被不再维护,主要原因是 Linux 目前对于异步的支持不完善,导致 Netty5 花了大代价,性能相对 Netty4 不但没有提升,甚至还会降低。

总结

  • Reactor 是同步非阻塞网络模型,Proactor 是异步非阻塞网络模型;

  • Reactor 是 I/O 多路复用和线程池的完美结合;

  • Reactor模型看似高深,其实是生活中很多真实案例的写照,比如:

    1. 夜市一个老板一辆推车的单人炒粉模式,从点菜,出餐,结算都是老板一人完成,这个就对应了 单 Reactor单线程模型;
    2. 医院叫号看病就对应了 单 Reactor多线程模型,一个叫号机负责叫号,多名医生负责接待病人;
    3. 大型餐饮就餐对应了 多 Reactor多线程模型,一个接待员负责接客送客,多名服务员,每名服务员负责几桌客人,然后有专门的端菜人员负责给客人端菜,比如:海底捞;
  • Reactor思维在日常开发中也会经常使用,最常用的是单线程处理,当并发量比较大时引进线程池,把业务细分,专门的线程处理专门的事情,这样就和 Reactor 模型的演变有异曲同工之妙;

  • Proactor 主要是采用异步的方式来处理 IO 事件(比如:叫外卖,下单支付后不需要关注,直接处理自己的事情,等外卖好了之后,外卖小哥会把主动把外卖送到你手上),不过目前 Linux 对 AIO支持的不太友好,使用该模型的 Netty5 最终也为此夭折了;

标签:网络通信,Reactor,模型,Handler,线程,事件,Proactor
From: https://blog.51cto.com/u_15872442/7341124

相关文章

  • 设计一个网络通信协议
    [email protected],2023Description设计一个网络通信协议大多数时候,并不需要进行协议设计,只需要使用成熟的协议就行了。但架不住少数时候的存在,所以就需要了解如何去设计一个协议。实际上协议工程学是一门专门的学科,而且互联网络常见......
  • X710网卡LACP模式下ifdown网卡后交换机侧依然处于UP状态,导致网络通信异常
    以下配置属于临时配置,重启后失效,具体建议在bios或者固件中解决。主要包含两个配置:1、使用ifdown命令关闭网卡无法使linkdown,交换机侧依然认为端口UP进行流量转发,无法正常通信2、在某些环境中,LACP可能无法正常工作,这些环境要求将包含LCAP信息的LLDP帧转发到网络堆栈。#查看网卡......
  • 封装socket网络通信模块
    封装socket网络通信模块-network由于TCP、UDP客户端、服务端的操作流程固定,所以为了后期使用方便,把socket网络通信封装成网络模块并生成libnw.so共享库头文件network.h#ifndefNETWORK_H#defineNETWORK_H#include<netinet/in.h>#include<stdbool.h>#include<stdint.h>......
  • Qt下的基本TCP网络通信流程
    给大家讲一下如何使用Qt相关类的进行TCP通信。前置知识:c++基础、qt基础、网络基础使用Qt提供的类进行基于TCP的套接字通信需要用到两个类:​ QTcpServer:服务器类,用于监听客户端连接以及和客户端建立连接。​ QTcpSocket:通信的套接字类,客户端、服务器端都需要使用。这两个套......
  • QT网络通信
    QT进行TCP网络通信:1.TCP是C/S模式的需要建立连接的网络通信架构,建立连接需要进行三次握手,断开连接需要四次握手。2.服务器模式:需要先创建监听套接字,通过bind函数进行ip和端口绑定,通过listen函数监听客户端的连接请求,通过accept函数处理客户端的连接请求并返回通信套接字进行通信......
  • process explorer 可以查看进程的网络通信情况 收发字节数
      网络里可以查看的选项:  DLL里可以看到: ......
  • reactor.core.Exceptions$ErrorCallbackNotImplemented: java.lang.IndexOutOfBoundsE
    生产环境好好的,突然前端请求全部跨域,请求500。gateway报错。reactor.core.Exceptions$ErrorCallbackNotImplemented:java.lang.IndexOutOfBoundsException:Index:0,Size:0。所有的接口都报。原因由于gateway也集成了springboot-admin,开启了应用程序的actuator端点,导致......
  • android网络通信之HTTP协议教程实…
    在现在的开发和应用中,网络通讯是必不可少的。虽然还是比较怀念小时候,抱着一台95在那里玩单机游戏玩的天昏地暗的时光,但是,现在,就算一个幼儿园的小盆友如果问你要手机玩游戏,突然发现居然买不了冰激凌草莓果汁什么的去喂talkinggina,或者切出一个超爆的水果分数却传不到网上去炫......
  • Java中常见的网络通信模型
    目前最近仔学习RocketMQ以及Dubbo还有Spring5框架的底层部分,了解到这些技术的底层都是采用的Netty作为底层的通信的软件,于是便需要详细了解以下网络中的通信的模型以及Netty的通信模型原理。本篇是通过Redis以及Netty进行网络通信模型的逐渐演化来进行介绍,其中还会夹杂着一些比......
  • SQL Server 的网络通信机制
    问题我试图了解SQLServer如何在网络上进行通信,因为我必须告诉我的网络团队在防火墙上打开哪些端口,以便边缘Web服务器与内部的SQLServer进行通信。我需要知道什么? 解决方案为了了解需要在哪里打开什么,我们首先简单谈谈当今常用的两个主要协议:TCP-传输控制协议UDP......