Netty 系列目录 (https://www.cnblogs.com/binarylei/p/10117436.html)
本文介绍 DC Schmidt 大神的一篇文章《Reactor: an object behavioral pattern for concurrent event demultiplexing and event handler dispatching》
反应器设计模式(Reactor pattern)是一种为处理并发服务请求,并将请求提交到一个或者多个服务处理程序的事件设计模式。当客户端请求抵达后,服务处理程序使用多路分配策略,由一个非阻塞的线程来接收所有的请求,然后派发这些请求至相关的工作线程进行处理。 Reactor模式主要包含下面几部分内容。
初始事件分发器(Initialization Dispatcher) :用于管理 Event Handler,定义注册、移除 EventHandler 等。它还作为 Reactor 模式的入口调用 Synchronous Event Demultiplexer 的 select 方法以阻塞等待事件返回,当阻塞等待返回时,根据事件发生的 Handle 将其分发给对应的 Event Handler 处理,即回调 EventHandler 中的 handle_event() 方法
同步(多路)事件分离器(Synchronous Event Demultiplexer) :无限循环等待新事件的到来,一旦发现有新的事件到来,就会通知初始事件分发器去调取特定的事件处理器。
系统处理程序(Handles) :操作系统中的句柄,是对资源在操作系统层面上的一种抽象,它可以是打开的文件、一个连接(Socket)、Timer 等。由于 Reactor 模式一般使用在网络编程中,因而这里一般指 Socket Handle,即一个网络连接(Connection,在 Java NIO 中的 Channel)。这个 Channel 注册到 Synchronous Event Demultiplexer 中,以监听 Handle 中发生的事件,对 ServerSocketChannnel 可以是 CONNECT 事件,对 SocketChannel 可以是 READ、WRITE、CLOSE 事件等。
事件处理器(Event Handler) : 定义事件处理方法,以供 Initialization Dispatcher 回调使用。
(1) Part A
对于一个事件驱动的分布式日志登录服务系统,如下图1所示。
客户端应用通过日志服务来录入它们当前状态和记录,这些状态可记录可能包含了错误通知信息、断点调试信息等。日志记录被发送到一个中央日服务器上,该服务器可以处理日志和连接用户请求。客户端想要记录日志信息,首先必须发送一个连接请求给服务器。服务器通过一个“处理工厂”来监听客户端对应的地址信息,以等待这些连接请求的到来。当一个连接请求到来时,“处理工厂”就创建一个handle,其代表了连接的端点,用来建立客户端和服务器之间的连接。当handle收到来自客户端的请求连接时,就会返回给服务器。一旦客户端连接成功,它们就可以同时发送日志记录到服务器。
(2) Part B
或许最有效的方法来开发一个并发日志系统是使用多线程,这样可以同时处多个理客户端请求,如下图2所示。
然而,多线程实现这样的分布式日志系统可能会面临下面的问题:
(3) Part C
针对上面的问题,可以集成同步多路分解事件并分发相应的事件处理程序来处理相应的事件。对于每一个应用程序所提供的服务,引入一个单独的事件处理器处理某些类型的事件。所有事件处理程序实现了相同的接口。事件处理程序注册一个初始调度程序,它使用一个同步事件信号分离器等待事件发生。当事件发生时,同步事件信号分离器通知初始调度器,它同步告知事件处理程序去关联对应的事件。事件处理程序然后分派事件到实现了所请求服务的方法中。
客户端连接到日志服务器所经过的一系列步骤如下图所示:
日志服务器记录日志所经过的一系列步骤如下图所示:
针对上面的问题,可以集成同步多路分解事件并分发相应的事件处理程序来处理相应的事件。对于每一个应用程序所提供的服务,引入一个单独的事件处理器处理某些类型的事件。所有事件处理程序实现了相同的接口。事件处理程序注册一个初始调度程序,它使用一个同步事件信号分离器等待事件发生。当事件发生时,同步事件信号分离器通知初始调度器,它同步告知事件处理程序去关联对应的事件。事件处理程序然后分派事件到实现了所请求服务的方法中。
上述日志系统的 Reactor 模式类图如下所示:
参考:
每天用心记录一点点。内容也许不重要,但习惯很重要!