栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Reactor & Proactor 设计模式

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Reactor & Proactor 设计模式

Reactor & Proactor 设计模式

​ 平时接触的开源产品如Redis, 事件模型都使用的Reactor模式; 而同样做事件处理的Proactor, 由于操作系统的原因, 相关的开源产品较少.

1. Reactor 模式 简介

一种为处理并发服务请求, 并将请求提交到一个或者多个服务处理程序的事件设计模式.

当客户端请求抵达后, 服务处理程序使用多路分配策略, 由一个非阻塞的线程来接收所有的请求, 然后派发这些请求至相关的工作线程进行处理.

基本组成

初始事件分发器(Initialization Dispatcher)

用于管理Event Handler, 定义注册, 移除EventHandler等; 还作为Reactor模式的入口调用Synchronous Event Demultiplexer的select方法以阻塞等待事件返回, 当阻塞等待返回时, 根据事件发生的Handle将其分发给对应的Event Handler处理, 即回调EventHandler中的handle_event()方法

多路事件分离器(Synchronous Event Demultiplexer)

无限循环等待新事件的到来, 一旦发现有新的事件到来, 就会通知初始事件分发器去调取特定的事件处理器.

系统处理程序(Handles)

操作系统中的句柄, 是对资源在操作系统层面上的一种抽象, 它可以是打开的文件、一个连接(Socket)、Timer等

由于Reactor模式一般使用在网络编程中, 因而这里一般指Socket Handle, 即一个网络连接(Connection, 在Java NIO中的Channel). 这个Channel注册到Synchronous Event Demultiplexer中, 以监听Handle中发生的事件, 对ServerSocketChannnel可以是CONNECT事件, 对SocketChannel可以是READ、WRITE、CLOSE事件等

事件处理器(Event Handler)

定义事件处理方法, 以供Initialization Dispatcher回调使用. 一部分是由Boss组成, 另一部分是由worker组成.

优缺点

并发系统常使用reactor模式代替常用的多线程的处理方式, 节省系统的资源, 提高系统的吞吐量.

多线程的处理

为每个单独到来的请求, 专门启动一条线程, 这样的话造成系统的开销很大, 并且在单核的机上, 多线程并不能提高系统的性能, 除非在有一些阻塞的情况发生. 否则线程切换的开销会使处理的速度变慢.

Reactor模式的处理

服务器端启动一条单线程, 用于轮询IO操作是否就绪, 当有就绪的才进行相应的读写操作, 这样的话就减少了服务器产 生大量的线程, 也不会出现线程之间的切换产生的性能消耗.

本质

两种处理方式都是基于同步的, 多线程的处理是我们传统模式下对高并发的处理方式, Reactor模式的处理是现今面对高并发和高性能一种主流的处理方式.

类设计

各个类图含义:

Handle 句柄: 用来标识socket连接或是打开文件;

Synchronous Event Demultiplexer(同步事件多路分解器): 由操作系统内核实现的一个函数; 用于阻塞等待发生在句柄集合上的一个或多个事件;

Event Handler: 事件处理接口

Concrete Event HandlerA: 实现应用程序所提供的特定事件处理逻辑

Reactor: 反应器, 定义一个接口, 实现以下功能:

供应用程序注册和删除关注的事件句柄;运行事件循环;有就绪事件到来时, 分发事件到之前注册的回调函数上处理

Initiation Dispatcher: 用于管理Event Handler, 即EventHandler的容器, 用以注册、移除EventHandler等

2. Proactor模式

运用于异步I/O操作, Proactor模式中, 应用程序不需要进行实际的读写过程, 它 只需要从缓存区读取或者写入即可, 操作系统会读取缓存区或者写入缓存区到真正的IO设备. Proactor中写入操作和读取操作, 只不过 感兴趣的事件是写入完成事件.

基本组成

Handle 句柄: 用来标识socket连接或是打开文件;

Asynchronous Operation Processor(异步操作处理器): 负责执行异步操作, 一般由操作系统内核实现;

Asynchronous Operation: 异步操作 ;

Completion Event Queue(完成事件队列): 异步操作完成的结果放到队列中等待后续使用.

Proactor: 主动器, 为应用程序进程提供事件循环; 从完成事件队列中取出异步操作的结果, 分发调用相应的后续处理逻辑;

Completion Handler(完成事件接口), 一般是由回调函数组成的接口;

Concrete Completion Handler(完成事件处理逻辑): 实现接口定义特定的应用处理逻辑;

从时序角度分析 Proactor 模式:

应用程序启动, 调用异步操作处理器提供的异步操作接口函数, 调用之后应用程序和异步操作处理就独立运行; 应用程序可以调用新的异步操作, 而其它操作可以并发进行.

应用程序启动Proactor主动器, 进行无限的事件循环, 等待完成事件到来.

异步操作处理器执行异步操作, 完成后将结果放入到完成事件队列.

主动器从完成事件队列中取出结果, 分发到相应的完成事件回调函数处理逻辑中.

3. Reactor vs Proactor模式 实现角度

Reactor实现了一个被动的事件分离和分发模型, 服务等待请求事件的到来, 再通过不受间断的同步处理事件, 从而做出反应.

Proactor实现了一个主动的事件分离和分发模型; 这种设计允许多个任务并发的执行, 从而提高吞吐量, 并可执行耗时长的任务 (各个任务间互不影响).

主动和被动方面

Reactor将handle放到select(), 等待可写就绪 然后调用write()写入数据; 写完处理后续逻辑. Reactor 被动的等待 指示事件的到来并做出反应它有一个等待的过程, 做什么都要先放入到监听事件集合中等待handler可用时再进行操作 .

Proactor调用aoi_write后立刻返回, 由内核负责写操作, 写完后调用相应的回调函数处理后续逻辑. Proactor 直接调用 异步读写操作, 调用完后立刻返回.

优点

​ Reactor 对于耗时短的处理场景处理高效; 操作系统可以在多个事件源上等待, 并且避免了多线程编程相关的性能开销和编程复杂性; 事件的串行化对应用是透明的, 可以顺序的同步执行而不需要加锁; 事务分离: 将与应用无关的多路分解和分配机制和与应用相关的回调函数分离开来.

​ Proactor性能更高, 能够处理耗时长的并发场景 .

缺点

​ Reactor处理耗时长的操作会造成事件分发的阻塞, 影响到后续事件的处理.

​ Proactor实现逻辑复杂; 依赖操作系统对异步的支持, 目前实现了纯异步操作的操作系统少.

而Unix/Linux系统对纯异步的支持有限, 应用事件驱动的主流还是通过select/epoll来实现.

4. 场景

​ Reactor: 同时接收多个服务请求, 并且依次同步的处理它们的事件驱动程序;

​ Proactor: 异步接收和同时处理多个服务请求的事件驱动程序

Reference

Lea, D. (2003). Scalable IO in Java. URL: http://gee.cs.oswego.edu/dl/cpjslides/nio.pdf.Reactor PatternProactor Pattern

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/759816.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号