高性能网络模式-Reactor
事实上,Reactor 模式也叫Dispatcher模式,即I/O 多路复⽤监听事件,收到事件后,根据事件类型分配(Dispatch)给某个进程/线程。Reactor 模式也是一种非阻塞同步网络模式。
Reactor 模式主要由 Reactor部分和处理事件部分这两个核⼼部分组成,它俩负责的事情如下:
- Reactor部分负责监听和分发事件,事件类型包含连接事件、读写事件;
- 处理事件部分负责处理事件,如 read -> 业务逻辑 -> send
Reactor 模式是灵活多变的,可以应对不同的业务场景,灵活在于:
- Reactor 的数量可以只有⼀个,也可以有多个;
- 处理事件部分可以是单个进程/线程,也可以是多个进程/线程
单Reactor单进程/线程
方案示意图
其中:
- Reactor对象用于监听所有的套接字以及按事件类型分发给不同对象。
- Acceptor对象用于listen套接字事件发生后的建立新连接。
- Hander对象用于普通套接字事件发生后处理对应的业务。
💡具体思想我们可以理解为:
- Reactor 对象通过IO 多路复⽤接⼝监听事件,收到事件后通过 dispatch 进⾏分发,具体分发给 Acceptor 对象还是 Handler 对象,还要看收到的事件类型;
- 如果是连接建⽴的事件,则交由 Acceptor 对象进⾏处理,Acceptor 对象会通过 accept⽅法 获取连接,并创建⼀个 Handler 对象来处理后续的响应事件;
- 如果不是连接建⽴事件, 则交由当前连接对应的 Handler 对象来进⾏响应;Handler 对象通过 read -> 业务处理 -> send 的流程来完成完整的业务流程。
该方案的缺点:
- 因为是单进程,所以无法充分利用多核CPU性能。
- Hander对象在处理业务的时候,整个进程是无法处理其他连接的事件的,如果业务处理耗时比较长的话,会造成响应的延迟,因此适用于业务处理快速的场景,比如Redis。
单Reactor多进程/线程
方案示意图:
相比与单进程:
- Hander对象不再负责业务的处理逻辑,只负责数据的接收和发送。
- 添加了线程池方案,将对应的要处理的业务逻辑交由线程池中的线程处理。
💡方案思想:
- Reactor 对象通过多路复用监听事件,收到事件后通过 dispatch 进⾏分发,具体分发给 Acceptor 对象还是 Handler 对象,还要看收到的事件类型;
- 如果是连接建⽴的事件,则交由 Acceptor 对象进⾏处理,Acceptor 对象会通过 accept⽅法 获取连接,并创建⼀个 Handler 对象来处理后续的响应事件;
- 如果不是连接建⽴事件, 则交由当前连接对应的 Handler 对象来进⾏响应;
- Handler 对象不再负责业务处理,只负责数据的接收和发送,Handler 对象通过 read 读取到数据后,会将数据发给线程池中的空闲⼦线程⾥的 Processor 对象进⾏业务处理;
- ⼦线程⾥的 Processor 对象就进⾏业务处理,处理完后,将结果发给主线程中的 Handler对象,接着由 Handler 通过 send ⽅法将响应结果发送给 client;
多线程的方案优势在于能够充分利用多核CPU的性能,但是引入了多线程,自然也带来了多线程资源竞争的问题。
多Reactor多进程/线程
单 Reactor的模式还有个问题,因为⼀个 Reactor 对象承担所有事件的监听和分发,⽽且只在主线程中运⾏,在⾯对瞬间⾼并发的场景时,容易成为性能的瓶颈的地⽅
那我们此时会想到什么?不错!再引入Reactor!
示意图:
相比于单Reactor的改进:
- 通过将需要监听的套接字分布在多个Reactor上,从而减轻主线程主Reactor的负担。
- 主线程的Reactor对象只负责监听listen套接字并建立新连接。
💡方案思想:
- 主线程中的 MainReactor 对象通过 select 监控连接建⽴事件,收到事件后通过 Acceptor对象中的 accept 获取连接,将新的连接分配给某个子线程;
- ⼦线程中的 SubReactor 对象将 MainReactor 对象分配的连接加⼊ select 继续进⾏监听,并创建⼀个 Handler ⽤于处理连接的响应事件;
- 如果有新的事件发⽣时,SubReactor 对象会调⽤当前连接对应的 Handler 对象来进⾏响应;
- Handler 对象通过 read -> 业务处理 -> send 的流程来完成完整的业务流程;
⭐️⭐️⭐️优点:
- 主线程和⼦线程分⼯明确,主线程只负责接收新连接并将新连接交给子线程,⼦线程负责完成该连接后续的监听和业务处理。
- 主线程和⼦线程的交互很简单,主线程只需要把新连接传给⼦线程,⼦线程⽆须返回数据,直接就可以在⼦线程将处理结果发送给客户端。
相关文章:

高性能网络模式-Reactor
事实上,Reactor 模式也叫Dispatcher模式,即I/O 多路复⽤监听事件,收到事件后,根据事件类型分配(Dispatch)给某个进程/线程。Reactor 模式也是一种非阻塞同步网络模式。 Reactor 模式主要由 Reactor部分和处…...

gRpc的四种通信方式详细介绍
🌷🍁 博主猫头虎 带您 Go to New World.✨🍁 🦄 博客首页——猫头虎的博客🎐 🐳《面试题大全专栏》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺 &a…...

JWT令牌的介绍
目录 一、什么是JWT 二、JWT令牌和Cookie客户端、Session服务端对比 三、特点与注意事项 四、使用场景 优点: 五、结构组成 一、什么是JWT JWT(JSON Web Token)是一种用于在网络应用间传递信息的开放标准(RFC 7519&#x…...

C语言入门 Day_9 条件判断
目录 前言: 1.if判断 2.else判断 3.易错点 4.思维导图 前言: 我们知道比较运算和逻辑运算都会得到一个布尔型的数据,要么为真(true),要么为假(false)。 今天我们来学习真和假在…...

Nodejs-nrm:快速切换npm源 / npm官方源和其他自定义源之间切换
一、理解 Nodejs nrm Nodejs nrm 是一个管理 npm 源的工具。由于 npm 在国内的速度较慢,很多开发者会使用淘宝的 npm 镜像源,但是也会遇到一些问题,例如某些包在淘宝镜像源中不存在,或者淘宝镜像源本身也会有问题。 Nodejs nrm …...

数据驱动洞察:各种词频分析技术挖掘热点数据
一、引言 随着信息时代的发展,人们的关注点日益复杂多样。社交媒体、新闻网站和论坛等平台上涌现了大量的信息,这使得热点分析成为了解社会热点话题和舆情动向的重要手段。词频统计是热点分析的基础,本文将分别介绍基于ElasticSearch、基于S…...
ES6-简介、语法
ES6 ES6简介 ECMAScript 6(简称ES6)是于2015年6月正式发布的JavaScript语言的标准,正式名为ECMAScript 2015(ES2015)。它的目标是使得JavaScript语言可以用来编写复杂的大型应用程序,成为企业级开发语…...

诚迈科技子公司智达诚远与Unity中国达成合作,打造智能座舱新时代
2023 年 8 月 23 日,全球领先的实时 3D 引擎 Unity 在华合资公司 Unity 中国举办发布会,正式对外发布 Unity 引擎中国版——团结引擎,并带来专为次世代汽车智能座舱打造的团结引擎车机版。发布会上,诚迈科技副总裁、诚迈科技子公司…...

算法与数据结构(十)--图的入门
一.图的定义和分类 定义:图是由一组顶点和一组能够将两个顶点连接的边组成的。 特殊的图: 1.自环:即一条连接一个顶点和其自身的边; 2.平行边:连接同一对顶点的两条边; 图的分类: 按照连接两个顶点的边的…...
【Go 基础篇】Go语言 init函数详解:包的初始化与应用
介绍 在Go语言中,init() 函数是一种特殊的函数,用于在包被导入时执行一次性的初始化操作。init() 函数不需要手动调用,而是在包被导入时自动执行。这使得我们可以在包导入时完成一些必要的初始化工作,确保包的使用具有正确的环境…...

wazuh环境配置及漏洞复现
目录 一、wazuh配置 1进入官网下载OVA启动软件 2.虚拟机OVA安装 二、wazuh案例复现 1.wazuh初体验 2.这里我们以SQL注入为例,在我们的代理服务器上进行SQL注入,看wazuh如何检测和响应 一、wazuh配置 1进入官网下载OVA启动软件 Virtual Machine (O…...

Java接收前端请求体方式
💗wei_shuo的个人主页 💫wei_shuo的学习社区 🌐Hello World ! 文章目录 RequestBodyPathVariableRequestParamValidated方法参数校验方法返回值校验 RequestHeaderHttpServletRequest ## Java接收前端请求体的方式 请求体…...

私有化部署即时通讯平台,30分钟替换钉钉和企业微信
随着企业对即时通讯和协作工具的需求不断增长,私有化部署的即时通讯平台成为企业的首选。WorkPlus作为有10余年行业深耕经验与技术沉淀品牌,以其安全高效的私有化部署即时通讯解决方案,帮助企业在30分钟内替换钉钉和企业微信。本文将深入探讨…...

如何深入理解 Node.js 中的流(Streams)
Node.js是一个强大的允许开发人员构建可扩展和高效的应用程序。Node.js的一个关键特性是其内置对流的支持。流是Node.js中的一个基本概念,它能够实现高效的数据处理,特别是在处理大量信息或实时处理数据时。 在本文中,我们将探讨Node.js中的流…...

MSP430FR2xxx开发(一)添加driverlib
一、新建工程 根据自己手上的硬件型号新建工程,文中已MSP430FR2355为例。 二、添加driverlib 首先去官方下载driverlib. https://www.ti.com.cn/tool/cn/MSPDRIVERLIB?keyMatchMSP430%20DRIVERLIB#downloads 下载后的内容如下: 我这里就选择MSP430…...

【C++】做一个飞机空战小游戏(九)——发射子弹的编程技巧
[导读]本系列博文内容链接如下: 【C】做一个飞机空战小游戏(一)——使用getch()函数获得键盘码值 【C】做一个飞机空战小游戏(二)——利用getch()函数实现键盘控制单个字符移动【C】做一个飞机空战小游戏(三)——getch()函数控制任意造型飞机图标移动 【C】做一个飞…...
34.SpringMVC获取请求参数
SpringMVC获取请求参数 通过ServletAPI获取 将HttpServletRequest作为控制器方法的形参,此时HttpServletRequest类型的参数表示封装了当前请求的请求报文的对象 index.html <form th:action"{/test/param}" method"post">用户名&#…...

TC1016-同星4路CAN(FD),2路LIN转USB接口卡
TC1016是同星智能推出的一款多通道CAN(FD)和LIN总线接口设备,CANFD总线速率最高支持8M bps,LIN支持速率0~20K bps,产品采用高速USB2.0接口与PC连接,Windows系统免驱设计使得设备具备极佳的系统兼容性。 支…...
Android源码——从Looper看ThreadLocal
1 概述 ThreadLocal用于在当前线程中存储数据,由于存储的数据只能在当前线程内使用,所以自然是线程安全的。 Handler体系中,Looper只会存在一个实例,且只在当前线程使用,所以使用ThreadLocal进行存储。 2 存储原理 …...

16、Flink 的table api与sql之连接外部系统: 读写外部系统的连接器和格式以及JDBC示例(4)
Flink 系列文章 1、Flink 部署、概念介绍、source、transformation、sink使用示例、四大基石介绍和示例等系列综合文章链接 13、Flink 的table api与sql的基本概念、通用api介绍及入门示例 14、Flink 的table api与sql之数据类型: 内置数据类型以及它们的属性 15、Flink 的ta…...

React第五十七节 Router中RouterProvider使用详解及注意事项
前言 在 React Router v6.4 中,RouterProvider 是一个核心组件,用于提供基于数据路由(data routers)的新型路由方案。 它替代了传统的 <BrowserRouter>,支持更强大的数据加载和操作功能(如 loader 和…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端
🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...
Leetcode 3577. Count the Number of Computer Unlocking Permutations
Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接:3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯,要想要能够将所有的电脑解锁&#x…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南
🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...

QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...
【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具
第2章 虚拟机性能监控,故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令:jps [options] [hostid] 功能:本地虚拟机进程显示进程ID(与ps相同),可同时显示主类&#x…...

有限自动机到正规文法转换器v1.0
1 项目简介 这是一个功能强大的有限自动机(Finite Automaton, FA)到正规文法(Regular Grammar)转换器,它配备了一个直观且完整的图形用户界面,使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...
Pinocchio 库详解及其在足式机器人上的应用
Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库,专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性,并提供了一个通用的框架&…...

CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)
漏洞概览 漏洞名称:Apache Flink REST API 任意文件读取漏洞CVE编号:CVE-2020-17519CVSS评分:7.5影响版本:Apache Flink 1.11.0、1.11.1、1.11.2修复版本:≥ 1.11.3 或 ≥ 1.12.0漏洞类型:路径遍历&#x…...