Proactor模式和Reactor模式 是应用服务器前端框架最为被谈起的两个框架。
对于Reactor模式来说,IO多路复用的机制就是其最典型的实现,多路事件分离器,Reactor的角色,Handler事件处理机制等等。
对于Proactor模式,整体的架构图和Proactor模式比较像,下面借着这张图来仔细分析一下:

Initiator:就是客户端,客户端的目的是进行操作,也就是Asynchronous Operation操作;
Asynchronous Operation:异步操作,类似于与慢速设备进行交互,但是这里并不是阻塞的,而是非阻塞的交互方式;
Completion Handler:事件处理器,当异步事件完成后,调用这个完成处理器;
Asynchronous Operation Process:异步操作执行器,它的任务是将客户端注册的完成事件作为key值,压入到完成操作系统的完成事件监听队列中;
Completion Event Queue:操作系统的监听事件完成队列,可以理解为操作系统中的xxxq,类似于freebsd中的kqueue;
Asynchronous Event Demultiplexer:多路事件分离器,和Reactor的多路分离器差不多,只不过这里不是select,而是异步时间队列的分离器,这个分离器主要的任务是从客户端的异步操作执行器告知的监听完成事件的key值,实时进行监听,当事件完成后,立刻通知Proactor中注册的Completion Handler,调用业务自己实现的完成Handler去执行完成后的业务逻辑。
Proactor:Proactor模式的管控核心,和Reactor一样,同样是持有了n个业务注册的handler,当多路事件分离器监测到完成事件发生的时候,立刻通知客户端注册的handler,执行回调的业务逻辑,完成整个流程。
抛开上述的操作系统中的部分,从最终类图的映射角度来看,

和Reactor类图基本上是相差无几,但是图中多出了一个Asynchronous Operation Process,异步操作执行器这个组件,这个多余出来的东西就是二者之间的区别。
对于Proactor来说,需要处理对应得是完成事件,以下图的典型的浏览器应用为例:

应用服务器前端使用Proactor模式,与操作系统之间的回调是在事件完成之后,这与Reactor是完全不同的,Reactor是在IO准备就绪的时候来回调事件,
对应的IO操作都是由用户态的程序来进行处理,因此这部分是阻塞的,因而Reactor这种模式说白了就是IO多路复用的机制。
而Proactor模式,关注的是事件的完成:

它要求操作系统必须支持异步的IO,其原因就是Proactor模式要求操作系统需要将客户端的关注的事件请求的数据,直接放到用户态的缓冲区中,而不是放到操作系统的内核缓冲区,让用户自己定义的handler去进行自己进行IO操作,Proactor模式直接就是将数据放到了用户态的缓冲区中,应用客户端直接就可以在handler中拿数据干活,基本上没有任何的延迟和阻塞,这就是Proactor模式优异的地方之一。
但是,从目前的技术角度来看,操作系统的AIO技术在不同操作系统上性能和可靠性有很大区别的,因此目前的Proactor模式,在java中在JDK7,8的时候
随着NIO2.0的JSR才刚刚引入进来,对于比较老的框架,如C++的ACE框架,也有对应的Proactor框架,如下:

ACE的架构框图,针对于ACE_Asynch_Read_Stream,ACE_Asynch_Write_Stream这两个组件实际就是操作系统AIO接口的封装,
ACE_Async_Acceptor,ACE_Async_Connector 分别是客户端和服务器端 对异步操作的处理器。
整体上Proactor框架基本和Proactor模式差不多,但是因为ACE出现的事件,AIO系统调用不稳定,因此ACE的Proactor框架最终实质
还有由IO多路复用的底层机制来实现的,相当于最终凑成了Proactor模式,这也是这块为什么被诟病的原因。
总结一下,Proactor模式实质是依托操作系统的AIO异步系统调用的架构模式,从模式的先进性来讲,要比Reactor等架构模式高级得多,但是取决于操作系统的AIO的稳定性和性能,目前大多数Proactor框架都是由IO多路复用的底层实现来凑成的,用的不多,JAVA 7,8也是刚刚随着NIO2.0进行引入的,直接调用的就是操作系统底层的AIO接口,但是目前的实施的案例还是少之又少,可以预计未来随着操作系统的AIO性能提升会越来越多。




