Doug Lea - 《Scalable IO in Java》
Using Multiple Reactors
![](https://img.haomeiwen.com/i13837765/7cf9c2e4052cf929.jpg)
上图就比较类似于netty的实现原理,mainReator
相当于Netty中的bossGroup ,subReactor
相当于Netty中的workerGroup,注意 wokerGroup中包含多个线程。
流程分析
- 将客户端向服务端发送一个事件,
mainReactor
通过acceptor
将事件分发给了subReactor
进而实现了Netty的事件分发机制。
Reactor模式的角色构成
![](https://img.haomeiwen.com/i13837765/374ad5d546de3cb1.jpg)
- Hanlde(句柄或者是 描述符): 本质上表示一种资源,是由操作系统来提供的,该资源用于表示一个个的事件,比如说文件描述符,网络Socket描述符。事件既可以来自于外部也可以来自于内部,外部事件比如 客户端网络连接,内部时间比如操作系统的定时器产生的事件。
- Synchronous Event Demultiplexer(同步事件分离器):它本身是一个系统调用,用于等待事件的发生。调用方在调用它的时候会被阻塞,一直阻塞到同步事件分离器有事件产生为止。对于linux中,就是I/O多路复用。在JAVA NIO中,就是selector。
- Event Handler(事件处理器):本身由多个回调方法构成,这些回调方法构成了与应用相关的对应某个事件的处理机制。
- Concrete Event Handler(具体事件处理器):是事件处理器的实现,它本身实现了事件处理器所提供的各个回调方法,从而实现了业务逻辑,类似于在JAVA NIO中实现
ChannelInboundHandler
或者是ChannelOutboundHandler
编写的一个个的处理器的实现。 - Initiation Dispatcher(初始分发器):实际上就是 Reactor角色提供事件调度方法,以及事件处理器的的注册,删除等。它本身是整个事件处理器的核心所在,Initiation Dispatcher 会通过同步事件分离器来等待事件的发生。一旦事件发生,他会先分离每个事件,然后调用事件处理器,最后调用事件相关回调方法来处理这些事件。
流程分析
-
当应用向 Initiation Dispatcher 注册具体的事件处理器时,应用会标识出该事件处理器希望Initiation Dispatcher在某个事件发生时通知其具体事件处理器,该事件与Handle关联。
-
Initiation Dispatcher会要求每个事件处理器向其传递内部的Handle,Handle对应了一个事件处理器。
-
当事件处理器注册完毕后,应用会调用handle_events方法来启动Initiation Dispatcher的事件循环。这时,Initiation Dispatcher会将每个注册的管理器的Handle合并起来,并使用同步事件分离器等待这些事件的发生。比如说TCP连接会使用select等待socket handle。
-
当与某个事件源对应的handle变为ready状态时,比如说tcp socket 变为等待读状态时,产生新的事件,同步事件分离器会通知Initiation Dispatcher。
-
Initiation Dispatcher 会触发event_handler回调方法,从而响应这个处于ready状态的Handle。当事件发生时,Initiation Dispatcher会将被事件源激活的Handle 作为 key 来寻找并分发适当的事件处理器回调方法。
-
Initiation Dispatcher会回调事件处理器的handle_events回调方法来执行特定应用的功能(类似于channleRead0())。
网友评论