参考博客:https://www.cnblogs.com/doit8791/p/7461479.html
参考视频:imooc 《Netty入门》
Reactor是一种处理客户端和服务端网络通信的IO模式。在Netty中被使用。
传统Java的网络通信模式:
(1)BIO:一个acceptor线程负责监听客户端的连接,一个请求一个应答,缺乏弹性伸缩能力。
(2)伪异步IO通信:线程池一个线程池负责连接,M个请求N个应答(N个线程)。当请求较多时,会造成线程池阻塞。
(3)NIO通信:构建一个缓冲区buffer; 通道channel(双向); 多路复用器selector
(4)AIO通信:读写方法异步,IO完成后主动通知程序; 不需要selector轮询,IO结果保存在Future类。
(1)(2)两种模式存在巨大缺陷。
Reactor模式有点类似于(3)。
在Reactor中,把大粒度线程拆分,这些被拆分的小线程或者子过程对应的是handler,每一种handler会出处理一种event。这里会有一个全局的管理者selector,我们需要把channel注册感兴趣的事件,那么这个selector就会不断在channel上检测是否有该类型的事件发生,如果没有,那么主线程就会被阻塞,否则就会调用相应的事件处理函数即handler来处理。典型的事件有连接,读取和写入,当然我们就需要为这些事件分别提供处理器,每一个处理器可以采用线程的方式实现。一个连接来了,显示被读取线程或者handler处理了,然后再执行写入,那么之前的读取就可以被后面的请求复用,吞吐量就提高了。
(1)(2)网络IO示意图:
Reactor模式示意图:
Reactor:负责响应IO事件,当检测到一个新的事件,将其发送给相应的Handler去处理。
Handler:负责处理非阻塞的行为,标识系统管理的资源;同时将handler与事件绑定。
由于只有单个线程,所以处理器中的业务需要能够快速处理完。
改进:逻辑处理部分由多线程完成
改进:多CPU,将Reactor拆分为两部分
结构组成:
Handle:对资源在操作系统层面上的一种抽象,它可以是打开的文件、一个连接(Socket)、Timer等。由于Reactor模式一般使用在网络编程中,因而这里一般指Socket Handle,即一个网络连接(Connection,在Java NIO中的Channel)。这个Channel注册到Synchronous Event Demultiplexer中,以监听Handle中发生的事件,对ServerSocketChannnel可以是CONNECT事件,对SocketChannel可以是READ、WRITE、CLOSE事件等。
Synchronous Event Demultiplexer:阻塞等待一系列的Handle中的事件到来,如果阻塞等待返回,即表示在返回的Handle中可以不阻塞的执行返回的事件类型。这个模块一般使用操作系统的select来实现。在Java NIO中用Selector来封装,当Selector.select()返回时,可以调用Selector的selectedKeys()方法获取Set<SelectionKey>,一个SelectionKey表达一个有事件发生的Channel以及该Channel上的事件类型。上图的“Synchronous Event Demultiplexer ---notifies--> Handle”的流程如果是对的,那内部实现应该是select()方法在事件到来后会先设置Handle的状态,然后返回。不了解内部实现机制,因而保留原图。
Initiation Dispatcher:用于管理Event Handler,即EventHandler的容器,用以注册、移除EventHandler等;另外,它还作为Reactor模式的入口调用Synchronous Event Demultiplexer的select方法以阻塞等待事件返回,当阻塞等待返回时,根据事件发生的Handle将其分发给对应的Event Handler处理,即回调EventHandler中的handle_event()方法。
Event Handler:定义事件处理方法:handle_event(),以供InitiationDispatcher回调使用。
Concrete Event Handler:事件EventHandler接口,实现特定事件处理逻辑。