本文概览:介绍了Reactor设计模式,并介绍NIO的对于Reactor简单实现,以及三种常见实现方式。

1 Reactor模式

1.1 介绍

1、模式目的

由上wiki中内容,可以把Reactor反应堆模式理解成一种事件驱动设计模式这个设计模式的作用是为了处理并发的请求时,避免为每个需要处理的请求创建一个线程。如下图中Event Loop实现了解复用和分发请求两个功能。

1

2、组件介绍

  • Handles:标识操作系统一种资源,如文件、socket。类比java nio中SelectKey或者Channel
  • 同步事件多路分解器Synchronous Event EDemultiplexer。阻塞所有的Handle,直到感兴趣的事件出现。类比java nio Selector,可以通过select()方法实现监听channel。
  • 分发器Initiation Dispatcher。通过调用同步事多路分解器的监听方法,发现有感兴趣事件就通知相应的事件处理器处理请求。
  • 事件处理器EventHandler,定义了一个接口,表示事件发生时的操作逻辑。
  • 具体事件处理器Concrete event handler。事件发生时具体的操作逻辑

43207594

1.2 JAVA NIO一个Reactor实例

类的关系图如下

37633001

1、Reactor代码

Reactor作用:

(1)初始化

  • 注册一个Channle到selector
  • 加载事件处理器EventHandler

(2)通过select监听满足事件的SelectKey

(3)根据事件类型,使用相应的事件处理器EventHandler来处理SelectKey

Reactor具体的代码如下:

2、定义一个EventHandler

(1)定义一个AcceptEventHandler

(2)ReadEventHandler,处理读事件

(3)WriteEventHandler,处理读事件

3、入口

4、测试,启动main之后,执行http://localhost:7070,在终端日志显示如下信息。

2 Java NIO 的reactor几种常用模式

也可以通过 :https://pan.baidu.com/s/1oWywgY724bFL7I3za3kkOQ  提取码: j9ur

2.1 背景

以socket请求为例。假设一个请求处理包括read、decode、compute、encode、send五个操作,如下图是传统处理请求的模式:为每一个请求分配一个线程。

46745478

上图对应具体代码如下:

在上面模式中,存在问题有:

  • 可能存在大量线程处于休眠状态,只是在等待输入或者输出数据就绪,这可能算是一种资源浪费。
  • 对于每一个线程需要分配栈内存,存在大量线程会造成内存占有过多。
  • 线程个数多时,上下文切换带来的开销也比较大。

为了解决上面问题,提供高系统并发能力,通过基于Java NIO事件驱动的Reactor模式来实现,好处在于:

  • 使用较少的线程就可以处理很多连接,减少了内存管理(线程需要分配线程栈)和线程上下文切换所带来的开销。
  • 当没有I/O操作需要处理时,cup可以执行其他线程

具体Reactor分为三种:

  • Basic Reactor Dessign,将原来一个请求一个线程模式改变为事件监听模式,即一个线程监听多个请求。
  • Worker Thread Pools,将处理请求中非IO操作放置线程池处理
  • Using Multiple Reactors,定义多个Reactor,相当于单机部署多个app,提高CPU和IO利用率。

2.2 Basic Reactor Design

通过一个线程进行监听请求,当监听到事件之后,进行处理请求

52168634

1、定义Reactor

2、定义SocketChannel的Handler

  • 处理读事件
  • 处理写事件

2.3 Worker Thread Pools

在“3.1 Basic Reactor Design”中是单线程处理所有触发事件channel,即单线程调用所有处理逻辑,相应的Reactor代码如下

“Worker Thread Pools模式”是面向多核CPU的。目前的CPU都是多核了,所以都是可以支持该模式的。此模式的主要思想:把一个请求处理中非IO操作的逻辑放置到线程池处理,这也是与“ 3.1 Basic Reactor Design”的区别,

52519351

对应代码如下:

2.4 Using Multiple Reactors

使用多个Reactor线程,可以将IO负载均衡到不同Reactor。与2.3节中“Worker Thread Pools”相比,这里每一个sub Reactor都可以看成是2.3节中“Worker Thread Pools”中一个Reactor。

52552636

对应代码如下

参考资料

1、Reactor An Object Behavioral Pattern for Demultiplexing and Dispatching Handles for Synchronous Events:http://www.dre.vanderbilt.edu/~schmidt/PDF/reactor-siemens.pdf

注意: 这篇文章是 Reacor模式的诞生的论文

2、Scalable IO in Java :http://gee.cs.oswego.edu/dl/cpjslides/nio.pdf

3、Understanding Reactor Pattern with Java NIO

http://kasunpanorama.blogspot.com/2015/04/understanding-reactor-pattern-with-java.html

对应的代码地址:https://github.com/kasun04/rnd/tree/master/nio-reactor

分类&标签

Category : NIO