Reactor反应器模式或应答者模式

Reactor反应器模式或应答者模式

Reactor模式是处理并发I/O常见的一种模式,用于同步I/O,其中心思想是将所有要处理的I/O事件注册到一个中心I/O多路复用器上,同时主线程阻塞在多路复用器上,一旦有I/O事件到来或是准备就绪,多路复用器将返回并将相应I/O事件分发到对应的处理器中。

Reactor是一种事件驱动机制,和普通函数调用不同的是应用程序不是主动的调用某个API来完成处理,恰恰相反的是Reactor逆置了事件处理流程,应用程序需提供相应的接口并注册到Reactor上,如果有相应的事件发生,Reactor将主动调用应用程序注册的接口(回调函数)。

Reactor模式是事件驱动模型,有一个或多个并发输入源,有一个Service Handler,有多个Request Handlers;这个Service Handler会同步的将输入的请求(Event)多路复用的分发给相应的Request Handler。从结构上,这有点类似生产者消费者模式,即有一个或多个生产者将事件放入一个Queue中,而一个或多个消费者主动的从这个Queue中Poll事件来处理;而Reactor模式则并没有Queue来做缓冲,每当一个Event输入到Service Handler之后,该Service Handler会主动的根据不同的Event类型将其分发给对应的Request Handler来处理。

在这里插入图片描述

Reactor模式称为反应器模式或应答者模式,是基于事件驱动的设计模式,拥有一个或多个并发输入源,有一个服务处理器和多个请求处理器,服务处理器会同步的将输入的请求事件以多路复用的方式分发给相应的请求处理器。

Reactor设计模式是一种为处理并发服务请求,并将请求提交到一个或多个服务处理程序的事件设计模式。当客户端请求抵达后,服务处理程序使用多路分配策略,由一个非阻塞的线程来接收所有请求,然后将请求派发到相关的工作线程并进行处理的过程。

在事件驱动的应用中,将一个或多个客户端的请求分离和调度给应用程序,同步有序地接收并处理多个服务请求。对于高并发系统经常会使用到Reactor模式,用来替代常用的多线程处理方式以节省系统资源并提高系统的吞吐量。

在处理网络请求时,通常具有两种体系结构。

基于线程 thread-based architecture
基于线程的体系结构会使用多线程来处理客户端的请求,每当接收一个请求便开启一个独立的线程来处理。这种方式虽然简单直观,但仅适用于并发访问不大的场景。因为线程是需要占用一定的内存资源,而且操作系统在线程之间的切换也需要一定的开销。当线程过多时显然会降低网络服务器的性能。另外,当线程在处理IO操作时,在等待输出的这段时间内线程是处于空闲状态,造成CPU资源浪费。

事件驱动 event-driver architecture
事件驱动体系结构是目前广泛使用的一种方式,这种方式定义了一系列的事件处理程序来响应事件的发生,而且将服务端接收连接和事件处理分离,事件本身只是一种状态的改变。在事件驱动的应用中,会将一个或多个客户端的服务请求分离demultiplex和调度dispatch给应用程序。

Reactor设计模式是event-driven architecture的一种实现方式,用于处理多个客户端并发的向服务器请求服务的场景。每种服务在服务器上可能由多个方法组成。Reactor会解耦并发请求的服务并分发给对应的时间处理器来处理。

从结构上看,Reactor类似于生产消费模式,也就是一个或多个生产者会将事件放入一个队列中,一个或多个消费者主动从队列中poll拉取事件进行处理。Reactor并没有使用队列来做缓冲,每当一个事件输入到服务处理程序之后,服务处理程序会主动根据不同的事件类型将其分发给对应的请求处理程序进行处理。

Reactor模式和生产者和消费者之间最大的区别在于

生产者消费者模式是基于队列queue的实现,能够解决生产端和消费端处理速度不同步的问题,队列可以采用先有的MQ产品来实现。

Reactor模式是基于事件驱动模型,当接收到请求后会将请求封装成事件,并将事件分发给相应处理事件的handler,handler处理完成后将时间状态修改为下一个状态,再由Reactor将事件分发给能够处理下一个状态的handle进行处理。
Reactor模式与Observer观察者模式在某些方面极为相似,当一个主体发生改变时,所有依属体都将得到通知。不过观察者模式与单个事件源关联,而反应器模式则于多个事件源关联。

Reactor模式的优点很明显:解耦、提升复用性、模块化、可移植性、事件驱动、细粒度的开发控制等。Reactor模式的缺点也很明显:模型复杂,涉及到内部回调、多线程处理、不容易调试、需要操作系统底层支持,因此导致不同操作系统可能会产生不一样的结果。总来而言,如果并发要求不是很高,可使用传统的阻塞线程池足够了。如果使用场景是产生瞬间大并发可使用Reactor模式来实现。

在Reactor中这些被拆分的小线程或子过程对应的处理程序,每一种处理程序会去处理一种事件。Reactor中存在一个全局管理者Selector,开发者需要将Channel注册到感兴趣的事件上,Selector会不断在Channel上检测是否有该类型的事件发生,如果没有主线程会被阻塞,否则会调用相应的事件处理函数来处理。

由于典型的事件包括连接、读取、写入,因此需要为这些事件分别提供对应的处理程序,每个处理程序可以采用线程的方式实现。一旦连接来了,而且显示被读取线程或处理程序处理了,则会再执行写入。那么之前的读取就可以被后面的请求复用,因此吞吐量就提高了。

传统的thread per connection中线程在真正处理请求之间是需要从socket中读取网络请求,由于读取完成之前线程本身是被阻塞的不能做任何事情,这就导致线程资源被占用,而线程资源本身很珍贵的,尤其是在处理高并发请求时。Rector模式指出在等待IO时,线程可以先退出,这样就会因为有线程等待IO而占用资源。但是这样原先的执行流程就没法还原了。因此可以利用事件驱动的方式,要求线程在退出之前向event loop事件循环中注册回调函数,这样IO完成时event loop事件循环就可以调用回调函数完成剩下的操作。所以Reactor模式通过减少服务器的资源消耗提供并发能力。

在这里插入图片描述

链接:https://www.jianshu.com/p/458e4b276607

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值