Reactor是由Schmidt, Douglas C提出的一种模式,在高并发server实现中广泛採用。

改模式採用事件驱动方式,当事件出现时,后调用对应的事件处理代码(Event Handler)。


这个模式是高并发server的基础。如nginx和lighttpd。

这两种对大并发,但每一个请求处理都非常快的场景非常适合。

通常的web訪问就是这个特点。


结构

包含了5个部分,当中handle和Synchronous Event Demultiplexer有OS实现。

Handles:

就是网络连接(connection),每一个网络连接都由一个handle表示。


Event(事件)
ACCEPT_EVENT:表示收到连接请求
READ_EVENT:表示收到数据
WRITE_EVENT:表示socket能够足够的缓冲区,能够向其写入数据。
TIMEOUT_EVENT:超时。

Java NIO不支持这个事件。

SIGNAL_EVENT:信号。

Java NIO不支持这个事件。

CLOSE_EVENT:该socket被关闭。Java NIO不支持这个事件。

Event Handler
事件处理代码,该对象实例(instance)是和handle关联的。

每一个Event Handler处理一个handle上的事件。一般的server中至少有两种事件处理代码:一个是用来接收连接请求(accept event handler),响应ACCEPT_EVENT。。一个用来处理接受的请求(connection event handler),响应READ_EVENT和WRITE_EVENT。


Synchronous Event Demultiplexer(事件多路分离系统)
该模式的核心,等待handles上的事件。没有事件出现时,一直堵塞(blocking);当某个(某些)handles上有时间产生时,返回。

这个是实现一般由操作系统提供。如linux的select、poll及epoll等。


Initiation Dispatcher
该对象负责管理Event Handlers(添加,删除等),当某个handle上有事件出现时,调用对应的
内部使用Synchronous Event Demultiplexer

reactor的论文中给出了实例代码
Logging_Acceptor是处理接收请求的event handler。

Logging_Handler是处理实际请求的event handler
Initiation_Dispatcher::instance是单利模式的Initiation Dispatcher

线程模型

论文中使用的是单线程模型。即一个线程同一时候处理接受请求和处理请求。该模型中。假设每一个请求的处理时间较长。则会影响真个系统的吞吐率。


更为普遍的是使用多线程模型。多线程的基本方式是1:n。

1个线程用来接受连接请求,运行accept event handler。
其它的线程用来处理连接请求,执行connection event handler。n的数量能够依据执行情况动态调整。假设每一个连接的处理非常快。可能一个线程就够了。假设处理的时间非常长,则可能一个连接就要有一个线程。

java NIO
java nio就是按照reactor模式设计的。

java nio中的主要抽象:

Selector:相当于Synchronous Event Demultiplexer
SelectionKey: 相当于event,和一个SocketChannel关联

SocketChannel:相当于handle
java nio中没有提供initial dispatcher的抽象,这部分功能须要用户自行实现。
java nio中没有提供event handler的抽象,这部分功能须要用户自行实现。

netty
作为API,java nio不会设计的非常全面。仅仅会提供主要的功能。对一般的用户来说,java nio提供的编程界面还是比較原始(pirmitive),不是非常easy使用。netty是一个网络编程框架。在java nio的基础上提供了更高层的抽象。netty的编程比起nio有极大的简化。

netty中提供了reactor的全部封装,用户在使用中仅仅需实现event handler就可以。


netty在event handler上又提供了一层抽象,ChannelPipeline和ChannelHandler。
ChannelPipeline类似于原来的event handler,用来处理连接请求。ChannelPipeline由若干个ChannelHandler构成,ChannelPipeline会分别调用这些ChannelHandler来处理连接请求。

这样的设计类似于servlet中的filter chain。

全部的ChannelHandler和在一起,形成了处理链路。


netty相同提供了对线程模型的支持,详细能够參考netty的文档。

proactor和reactor的差别

主要差别是在处理连接请求时的方式:

reactor: 收到事件后,同步处理。该请求没有完毕后。该线程不会再去处理其它请求。
proactor:收到事件,异步处理。

该请求会运行异步调用(如异步读写文件等),然后该请求调用返回,该线程会继续运行其它的请求。可是第一个请求并没有处理完毕,当异步操作完毕时,后有时间通知到第一个请求。完毕处理。proactor的编程会比較复杂。

reactor模式与java nio的更多相关文章

  1. the reactor pattern and java nio

    在<java NIO>作者PPT<How to Build a Scalable Multiplexed Server With NIO> 和 Doug Lea <Sca ...

  2. 知识联结梳理 : I/O多路复用、EPOLL(SELECT/POLL)、NIO、Event-driven、Reactor模式

    为了形成一个完整清晰的认识,将概念和关系梳理出来,把坑填平. I/O多路复用 I/O多路复用主要解决传统I/O单线程阻塞的问题.它通过单线程管理多个FD,当监听的FD有状态变化的时候的,调用回调函数, ...

  3. 【转载】高性能IO设计 & Java NIO & 同步/异步 阻塞/非阻塞 Reactor/Proactor

    开始准备看Java NIO的,这篇文章:http://xly1981.iteye.com/blog/1735862 里面提到了这篇文章 http://xmuzyq.iteye.com/blog/783 ...

  4. Java NIO系列教程(八)JDK AIO编程

    目录: Reactor(反应堆)和Proactor(前摄器) <I/O模型之三:两种高性能 I/O 设计模式 Reactor 和 Proactor> <[转]第8章 前摄器(Proa ...

  5. Java NIO系列教程(七) selector原理 Epoll版的Selector

    目录: Reactor(反应堆)和Proactor(前摄器) <I/O模型之三:两种高性能 I/O 设计模式 Reactor 和 Proactor> <[转]第8章 前摄器(Proa ...

  6. Java多线程:Linux多路复用,Java NIO与Netty简述

    JVM的多路复用器实现原理 Linux 2.5以前:select/poll Linux 2.6以后: epoll Windows: IOCP Free BSD, OS X: kqueue 下面仅讲解L ...

  7. Java NIO学习-预备知识

    java NIO加入了Channels.Buffers.Selector.通过他们可以为java的io添加非阻塞IO. 一.对于经典java IO库 1.除了Buffered开头的类,其他均没有加缓冲 ...

  8. Netty(七):EventLoop学习前导——Reactor模式

    了解Netty的人多少都会知道Netty的高性能的一个原因就是它是基于事件驱动的,而这一事件的原型就是Reactor模式. 所以在学习EventLoop前,很有必要先搞懂Reactor模式. 本文目录 ...

  9. JAVA NIO复习笔记

    1. JAVA NIO是什么? 从JDK1.4开始,java提供了一系列改进的输入/输出处理的新功能,这些功能被统称为新IO(New IO,简称NIO),新增了许多用于处理输入/输出的类,这些类都被放 ...

随机推荐

  1. linux下的查找命令

    whereis <程序名称> 查找软件的安装路径 -b 只查找二进制文件 -m 只查找帮助文件 -s 只查找源代码 -u 排除指定类型文件 -f 只显示文件名 -B <目录> ...

  2. W10子系统UBantu命令安装Redis及其启动

    W10子系统UBantu命令安装Redis及其启动 打开W10子系统UBantu 安装Redis $sudo apt-get install redis-server 启动Redis redis-se ...

  3. 前端实现input[type='file']上传图片预览效果

    众所周知JavaScript在设计上处于安全角度考虑,是不允许读写本地文件的(原因请自行百度): 但是在实际项目应用中,经常会使用到上传图片,并且可以让用户直接预览图片.对于此种做法有两种方法可以实现 ...

  4. C#-委托 lambda 匿名方法 匿名类型

    1.lambda 匿名方法 匿名类型 delegate void d1(); d1 d = delegate(){Console.WriteLine("this is a test" ...

  5. node 命令行输入控件 prompt.js

        function print(){ console.log.apply(console , arguments) } var step ,_lstStp ,_onConfirmInput ,_ ...

  6. CSS文本简单设置

    文本的设置直接影响到用户对界面的感受,好的文本设置能够让用户对界面有一种赏心悦目的感受,在这地方我们来简单的说说说对文本设置的时候,有哪些格式. 文本设置的时候我们应该注意什么: 平时我们文本设置的时 ...

  7. COGS 2479 奇怪的姿势卡♂过去 (bitset+折半)

    思路: 此题显然是CDQ套CDQ套树套树 (然而我懒) 想用一种奇怪的姿势卡过去 就出现了以下解法 5w*5w/8的bitset hiahiahia 但是空间会爆怎么办啊- 折半~ 变成5w*2.5w ...

  8. POJ 3368 线段树

    思路: 先统计在第i个位置当前数字已经出现的次数. 维护两个数组,一个是当前位置的数字最后一次出现的位置,另一个是当前位置的数字第一次出现的位置 查找的时候分为两种情况: 没有和边界相交(意会意会)的 ...

  9. ie浏览器检测不到cookie的问题

    之前做项目由于客户的要求设置缓存必须由后台来设置必须使用cookie(session是没问题的),后期设置时出现了登录页面与首页来还跳转的局面.原因就是首页没检测到登录后的缓存,而后台验证到确实已经是 ...

  10. C#如何生成一个随机种子for Random?

    就这么写: Random rand = new Random((int)DateTime.Now.Ticks); 或者这么写: Random rand = new Random(new Guid(). ...