实现Reactor反应堆模型:框架搭建
实现Reactor反应堆模型:框架搭建
Reactor模型是一种常用于处理大量并发I/O操作的设计模式,特别适用于服务器端的网络编程。该模型通过事件驱动的方式,将I/O操作的处理与具体的业务逻辑分离,从而提高系统的并发处理能力和响应速度。本文将详细介绍如何搭建一个Reactor反应堆模型的框架,包括核心组件的设计、线程池的管理、事件分发机制等关键方面。
一、Reactor模型概述
Reactor模型的核心思想是将I/O事件的处理流程划分为多个阶段,每个阶段由不同的组件负责处理。具体来说,Reactor模型通常包含以下几个关键组件:
- Reactor核心:负责监听和接收I/O事件,并将事件分发到相应的处理器进行处理。
- 事件处理器:根据事件类型,执行具体的业务逻辑处理。
- 事件分发器:将Reactor核心接收到的I/O事件分发到合适的事件处理器。
- 线程池:用于处理业务逻辑,以充分利用多核CPU资源,提高并发处理能力。
二、Reactor框架搭建
1. Reactor核心设计
Reactor核心是Reactor模型的核心组件,负责监听和接收I/O事件。在Java中,我们可以使用java.nio包下的Selector类来实现Reactor核心。Selector类能够同时监听多个Channel上的I/O事件,当某个Channel上有事件发生时,Selector会通知Reactor核心。
Reactor核心的设计需要包含以下几个关键部分:
- Selector的初始化:创建一个
Selector实例,并将其注册到操作系统的I/O多路复用机制上。 - Channel的注册:将需要监听的Channel注册到
Selector上,并指定感兴趣的事件类型(如读、写、连接等)。 - 事件循环:通过
Selector的select方法不断轮询是否有事件发生,一旦有事件发生,就获取事件的详细信息,并分发到相应的事件处理器。
2. 事件处理器设计
事件处理器是Reactor模型中处理具体业务逻辑的组件。在Reactor框架中,我们需要为每种事件类型设计一个对应的事件处理器。例如,对于读事件,我们可以设计一个读事件处理器;对于写事件,我们可以设计一个写事件处理器。
事件处理器的设计需要包含以下几个关键部分:
- 事件类型的识别:根据事件的类型(如读、写、连接等),执行相应的业务逻辑。
- 业务逻辑的处理:在事件处理器中,根据事件的具体信息(如Channel、缓冲区等),执行具体的业务逻辑。
- 结果的反馈:将业务逻辑的处理结果反馈给Reactor核心,以便进行后续的处理(如继续监听、关闭连接等)。
3. 事件分发器设计
事件分发器是Reactor模型中连接Reactor核心和事件处理器的桥梁。它的作用是将Reactor核心接收到的I/O事件分发到合适的事件处理器进行处理。
事件分发器的设计需要包含以下几个关键部分:
- 事件类型的映射:建立一个事件类型到事件处理器的映射关系,以便在接收到事件时能够快速找到对应的事件处理器。
- 事件的分发:根据事件类型,将事件分发到对应的事件处理器进行处理。
- 结果的收集:如果需要,可以收集事件处理器的处理结果,并进行后续的处理(如日志记录、统计等)。
4. 线程池管理
在Reactor模型中,线程池通常用于处理业务逻辑,以充分利用多核CPU资源,提高并发处理能力。线程池的设计需要包含以下几个关键部分:
- 线程池的初始化:根据系统的硬件资源和业务需求,初始化一个合适大小的线程池。
- 任务的提交:将需要处理的任务(如事件处理器的业务逻辑)提交到线程池中执行。
- 线程的管理:对线程池中的线程进行管理和监控,如线程的创建、销毁、复用等。
三、Reactor框架实现
以下是一个简单的Reactor框架的实现示例,包含了Reactor核心、事件处理器、事件分发器和线程池的关键部分。
// Reactor核心类
public class Reactor {private Selector selector;private EventDispatcher eventDispatcher;private ExecutorService executorService;public Reactor(int selectorThreads, int workerThreads) throws IOException {this.selector = Selector.open();this.eventDispatcher = new EventDispatcher();this.executorService = Executors.newFixedThreadPool(workerThreads);// 初始化事件处理器映射关系(这里需要手动添加)// eventDispatcher.registerEventHandler(...);// 启动多个Selector线程(这里为了简化,只使用一个Selector线程)new Thread(this::run).start();}private void run() {while (true) {try {// 轮询事件selector.select();// 处理事件Set<SelectionKey> selectedKeys = selector.selectedKeys();Iterator<SelectionKey> iterator = selectedKeys.iterator();while (iterator.hasNext()) {SelectionKey key = iterator.next();iterator.remove();// 分发事件eventDispatcher.dispatchEvent(key);}} catch (IOException e) {e.printStackTrace();// 可以考虑进行重试或者关闭Reactor}}}// 提交任务到线程池执行public void submitTask(Runnable task) {executorService.submit(task);}// 关闭Reactorpublic void shutdown() {try {selector.close();executorService.shutdown();} catch (IOException e) {e.printStackTrace();}}
}// 事件分发器类
public class EventDispatcher {// 事件处理器映射关系(可以使用Map实现)// private Map<EventType, EventHandler> eventHandlers = new HashMap<>();// 注册事件处理器(这里需要实现具体的注册逻辑)// public void registerEventHandler(EventType eventType, EventHandler eventHandler) {// eventHandlers.put(eventType, eventHandler);// }// 分发事件public void dispatchEvent(SelectionKey key) {// 根据key获取事件类型// EventType eventType = ...;// 获取对应的事件处理器// EventHandler eventHandler = eventHandlers.get(eventType);// 如果找到了事件处理器,则提交任务到线程池执行// if (eventHandler != null) {// reactor.submitTask(() -> eventHandler.handle(key));// } else {// // 处理未知事件类型(可以记录日志或者抛出异常)// }}
}// 事件处理器接口
public interface EventHandler {void handle(SelectionKey key);
}// 示例事件处理器类
public class ReadEventHandler implements EventHandler {@Overridepublic void handle(SelectionKey key) {// 读取数据的逻辑(需要实现具体的读取逻辑)// ...}
}// 主程序类
public class Main {public static void main(String[] args) throws IOException {Reactor reactor = new Reactor(1, 10);// 注册事件处理器(这里需要调用EventDispatcher的注册方法)// reactor.getEventDispatcher().registerEventHandler(...);// 启动服务器(需要实现具体的服务器启动逻辑,如绑定端口、监听连接等)// ...// 等待服务器关闭(可以通过守护线程或者其他方式实现)// ...// 关闭Reactor// reactor.shutdown();}
}
注意:上述代码是一个简化的Reactor框架实现示例,仅包含了Reactor核心、事件分发器和线程池的基本框架。在实际应用中,还需要实现具体的事件处理器、完善事件分发器的注册逻辑、实现服务器的启动和关闭逻辑等。此外,为了处理不同类型的I/O事件(如读、写、连接、断开连接等),还需要定义相应的事件类型,并为每种事件类型实现对应的事件处理器。
四、总结
Reactor模型是一种高效处理大量并发I/O操作的设计模式,通过事件驱动的方式将I/O操作的处理与具体的业务逻辑分离,从而提高系统的并发处理能力和响应速度。在搭建Reactor框架时,需要设计Reactor核心、事件处理器、事件分发器和线程池等关键组件,并考虑线程安全、性能优化等方面的问题。通过合理的框架设计和实现,可以构建一个高效、稳定、可扩展的Reactor服务器。
相关文章:
实现Reactor反应堆模型:框架搭建
实现Reactor反应堆模型:框架搭建 Reactor模型是一种常用于处理大量并发I/O操作的设计模式,特别适用于服务器端的网络编程。该模型通过事件驱动的方式,将I/O操作的处理与具体的业务逻辑分离,从而提高系统的并发处理能力和响应速度…...
UE5 样条线组件(未完待续)
按点生成模型 按距离生成 spline mesh 可缩放spline mesh...
计算机网络常见面试题(一):TCP/IP五层模型、TCP三次握手、四次挥手,TCP传输可靠性保障、ARQ协议
文章目录 一、TCP/IP五层模型(重要)二、应用层常见的协议三、TCP与UDP3.1 TCP、UDP的区别(重要)3.2 运行于TCP、UDP上的协议3.3 TCP的三次握手、四次挥手3.3.1 TCP的三次握手3.3.2 TCP的四次挥手3.3.3 随机生成序列号的原因 四、T…...
sql速度优化多条合并为一条语句
在 SQL 中,结合 CASE 和 SUM 可以实现根据特定条件进行分组求和。在 ThinkPHP 中也可以使用类似的方式进行数据库查询操作。 例如,假设有一个销售数据表,包含字段 product_id (产品 ID)、 quantity (销…...
用 PHP或Python加密字符串,用iOS解密
可以使用对称加密算法(如 AES)来加密和解密字符串。对称加密适合这种跨平台加密解密的需求,因为可以使用相同的密钥和算法在不同的编程语言和系统之间进行加密和解密。 下面展示如何使用 Python 或 PHP 进行加密,然后用 iOS (Swi…...
docker容器启动报错error creating overlay mount to /var/lib/docker/overlay2解决办法
背景:客户提供的机器用于部署服务,拿到发现docker是部署好的,但是selinux没有关闭,于是将/etc/selinux/config中的selinux设置成了disabled,但是并未重启,就继续部署服务了;结果几天后客户重启服…...
人工智能在智能家居中的应用
💓 博客主页:瑕疵的CSDN主页 📝 Gitee主页:瑕疵的gitee主页 ⏩ 文章专栏:《热点资讯》 人工智能在智能家居中的应用 人工智能在智能家居中的应用 人工智能在智能家居中的应用 引言 人工智能概述 定义与原理 发展历程 …...
MySQL数据库备份与恢复:全面深入指南
在数字化时代,数据已成为企业最宝贵的资产之一。数据库作为存储和管理这些数据的核心系统,其安全性和稳定性至关重要。MySQL,作为一款广泛使用的开源关系型数据库管理系统,因其高性能、高可靠性和易用性而受到众多企业和开发者的青…...
前端请求后端php接口跨域 cors问题
只需要后端在网站的入口文件 一般都是 index.php 加上 这几行代码就可以了 具体的参数可以根据需要去修改 header("Access-Control-Allow-Origin: *"); header(Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS); header(Access-Control-Allow-Heade…...
【软件工程】ATAM架构权衡评估方法
ATAM架构权衡评估方法 概述质量属性有哪些?质量属性的效用树怎么构建?如何确定质量属性的优先级? 概述 ATAM(Architecture Tradeoff Analysis Method)是一种系统架构评估方法,由卡梅隆大学软件工程协会提出…...
MFC 重写了listControl类(类名为A),并把双击事件的处理函数定义在A中,主窗口如何接收表格是否被双击
刚接触MFC遇到的问题,我在主对话框的.cpp里添加了表格的双击处理事件,但是没用,试了下添加单击的,发现居然可以进单击的处理函数,就很懵逼,然后我就把处理双击事件的函数添加到表格的类中,那这样…...
c和cpp的异常处理
### 课堂讨论 **老师**:今天我们来深入探讨一下C的异常处理机制。想象一下,我们正在玩一场探险游戏。你会遇到一些意外情况,比如掉进陷阱。这就像我们的程序在运行中遇到错误。我们该怎么处理呢?🤔 **学生**…...
monkey-安卓稳定性测试
一、adb执行命令 1.monkey随机事件指令: adb shell monkey -p com.tytu.enter --ignore-crashes --ignore-timeouts --ignore-security-exceptions -v -v -v --throttle 300 -s 121212 --pct-syskeys 0 --pct-anyevent 0 --pct-touch 100 --pct-motion 0 100000 2&…...
【贪心算法】贪心算法三
贪心算法三 1.买卖股票的最佳时机2.买卖股票的最佳时机 II3.K 次取反后最大化的数组和4.按身高排序5.优势洗牌(田忌赛马) 点赞👍👍收藏🌟🌟关注💖💖 你的支持是对我最大的鼓励&#…...
LeetCode 40-组合总数Ⅱ
题目链接:LeetCode40 欢迎留言交流,每天都会回消息。 class Solution {List<List<Integer>> rs new ArrayList<>();LinkedList<Integer> path new LinkedList<>();public List<List<Integer>> combinatio…...
STM32WB55RG开发(1)----开发板测试
STM32WB55RG开发----1.开发板测试 概述硬件准备视频教学样品申请源码下载产品特性参考程序生成STM32CUBEMX串口配置LED配置堆栈设置串口重定向主循环演示 概述 STM32WB55 & SENSOR是一款基于STM32WB55系列微控制器的评估套件。该套件采用先进的无线通信技术,支…...
误删分区数据恢复全攻略
一、误删分区现象描述 在日常使用电脑的过程中,我们可能会遇到一种令人头疼的情况——误删分区。这通常发生在用户对磁盘管理操作不当,或者在进行系统重装、分区调整时不慎删除了重要分区。误删分区后,原本存储在该分区的数据将无法直接访问…...
《XGBoost算法的原理推导》12-14决策树复杂度的正则化项 公式解析
本文是将文章《XGBoost算法的原理推导》中的公式单独拿出来做一个详细的解析,便于初学者更好的理解。 我们定义一颗树的复杂度 Ω Ω Ω,它由两部分组成: 叶子结点的数量;叶子结点权重向量的 L 2 L2 L2范数; 公式(…...
昇思大模型平台打卡体验活动:项目4基于MindSpore实现Roberta模型Prompt Tuning
基于MindNLP的Roberta模型Prompt Tuning 本文档介绍了如何基于MindNLP进行Roberta模型的Prompt Tuning,主要用于GLUE基准数据集的微调。本文提供了完整的代码示例以及详细的步骤说明,便于理解和复现实验。 环境配置 在运行此代码前,请确保…...
hadoop 3.x 伪分布式搭建
hadoop 伪分布式搭建 环境 CentOS 7jdk 1.8hadoop 3.3.6 1. 准备 准备环境所需包上传所有压缩包到服务器 2. 安装jdk # 解压jdk到/usr/local目录下 tar -xvf jdk-8u431-linux-x64.tar.gz -C /usr/local先不着急配置java环境变量,后面和hadoop一起配置 3. 安装had…...
Xshell远程连接Kali(默认 | 私钥)Note版
前言:xshell远程连接,私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...
Oracle查询表空间大小
1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...
Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...
在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module
1、为什么要修改 CONNECT 报文? 多租户隔离:自动为接入设备追加租户前缀,后端按 ClientID 拆分队列。零代码鉴权:将入站用户名替换为 OAuth Access-Token,后端 Broker 统一校验。灰度发布:根据 IP/地理位写…...
EtherNet/IP转DeviceNet协议网关详解
一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...
【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分
一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计,提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合:各模块职责清晰,便于独立开发…...
Spring是如何解决Bean的循环依赖:三级缓存机制
1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间互相持有对方引用,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...
短视频矩阵系统文案创作功能开发实践,定制化开发
在短视频行业迅猛发展的当下,企业和个人创作者为了扩大影响力、提升传播效果,纷纷采用短视频矩阵运营策略,同时管理多个平台、多个账号的内容发布。然而,频繁的文案创作需求让运营者疲于应对,如何高效产出高质量文案成…...
Docker 本地安装 mysql 数据库
Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker ;并安装。 基础操作不再赘述。 打开 macOS 终端,开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...
PAN/FPN
import torch import torch.nn as nn import torch.nn.functional as F import mathclass LowResQueryHighResKVAttention(nn.Module):"""方案 1: 低分辨率特征 (Query) 查询高分辨率特征 (Key, Value).输出分辨率与低分辨率输入相同。"""def __…...
