Netty Reator(三)Reactor 模型

Netty 系列目录 (https://www.cnblogs.com/binarylei/p/10117436.html)

本文介绍 DC Schmidt 大神的一篇文章《Reactor: an object behavioral pattern for concurrent event demultiplexing and event handler dispatching》

一、What:Reactor 模式是什么?

反应器设计模式(Reactor pattern)是一种为处理并发服务请求,并将请求提交到一个或者多个服务处理程序的事件设计模式。当客户端请求抵达后,服务处理程序使用多路分配策略,由一个非阻塞的线程来接收所有的请求,然后派发这些请求至相关的工作线程进行处理。 Reactor模式主要包含下面几部分内容。

  1. 初始事件分发器(Initialization Dispatcher) :用于管理 Event Handler,定义注册、移除 EventHandler 等。它还作为 Reactor 模式的入口调用 Synchronous Event Demultiplexer 的 select 方法以阻塞等待事件返回,当阻塞等待返回时,根据事件发生的 Handle 将其分发给对应的 Event Handler 处理,即回调 EventHandler 中的 handle_event() 方法

  2. 同步(多路)事件分离器(Synchronous Event Demultiplexer) :无限循环等待新事件的到来,一旦发现有新的事件到来,就会通知初始事件分发器去调取特定的事件处理器。

  3. 系统处理程序(Handles) :操作系统中的句柄,是对资源在操作系统层面上的一种抽象,它可以是打开的文件、一个连接(Socket)、Timer 等。由于 Reactor 模式一般使用在网络编程中,因而这里一般指 Socket Handle,即一个网络连接(Connection,在 Java NIO 中的 Channel)。这个 Channel 注册到 Synchronous Event Demultiplexer 中,以监听 Handle 中发生的事件,对 ServerSocketChannnel 可以是 CONNECT 事件,对 SocketChannel 可以是 READ、WRITE、CLOSE 事件等。

  4. 事件处理器(Event Handler) : 定义事件处理方法,以供 Initialization Dispatcher 回调使用。

一、Why:为什么使用 Reactor 模式?

(1) Part A

对于一个事件驱动的分布式日志登录服务系统,如下图1所示。

客户端应用通过日志服务来录入它们当前状态和记录,这些状态可记录可能包含了错误通知信息、断点调试信息等。日志记录被发送到一个中央日服务器上,该服务器可以处理日志和连接用户请求。客户端想要记录日志信息,首先必须发送一个连接请求给服务器。服务器通过一个“处理工厂”来监听客户端对应的地址信息,以等待这些连接请求的到来。当一个连接请求到来时,“处理工厂”就创建一个handle,其代表了连接的端点,用来建立客户端和服务器之间的连接。当handle收到来自客户端的请求连接时,就会返回给服务器。一旦客户端连接成功,它们就可以同时发送日志记录到服务器。

(2) Part B

或许最有效的方法来开发一个并发日志系统是使用多线程,这样可以同时处多个理客户端请求,如下图2所示。

然而,多线程实现这样的分布式日志系统可能会面临下面的问题:

  1. 可用性:服务器必须能够处理传入请求即使是等待其他请求到达的。特别是,一个服务器不能无限期地处理任何单一来源的事件而排斥其他事件源。因为这可能大大延迟响应其他客户的时间。
  2. 效率:一个服务器应该做到延迟最小化、吞吐量最大化,避免不必要地使用CPU。多线程可能会导致糟糕的性能由于上下文切换、同步和数据移动。
  3. 编程简洁:服务器的设计上应该简化使用合适的并发策略。多线程可能需要复杂的并发控制方案。
  4. 可移植性:多线程不是可用在所有操作系统平台。
  5. 适应性:集成新的或改进服务,如改变消息格式或添加服务器端缓存,应该承担最小的现有代码的修改和维护成本。例如,实现新应用程序服务应该不需要修改通用事件多路分解和调度机制。

(3) Part C

针对上面的问题,可以集成同步多路分解事件并分发相应的事件处理程序来处理相应的事件。对于每一个应用程序所提供的服务,引入一个单独的事件处理器处理某些类型的事件。所有事件处理程序实现了相同的接口。事件处理程序注册一个初始调度程序,它使用一个同步事件信号分离器等待事件发生。当事件发生时,同步事件信号分离器通知初始调度器,它同步告知事件处理程序去关联对应的事件。事件处理程序然后分派事件到实现了所请求服务的方法中。

客户端连接到日志服务器所经过的一系列步骤如下图所示:

日志服务器记录日志所经过的一系列步骤如下图所示:

二、Reactor 模型

针对上面的问题,可以集成同步多路分解事件并分发相应的事件处理程序来处理相应的事件。对于每一个应用程序所提供的服务,引入一个单独的事件处理器处理某些类型的事件。所有事件处理程序实现了相同的接口。事件处理程序注册一个初始调度程序,它使用一个同步事件信号分离器等待事件发生。当事件发生时,同步事件信号分离器通知初始调度器,它同步告知事件处理程序去关联对应的事件。事件处理程序然后分派事件到实现了所请求服务的方法中。

上述日志系统的 Reactor 模式类图如下所示:

参考:

  1. 《Reactor 模型》:https://blog.csdn.net/pistolove/article/details/53152708

每天用心记录一点点。内容也许不重要,但习惯很重要!

Netty Reator(三)Reactor 模型的更多相关文章

  1. Netty源码 reactor 模型

    翻阅源码时,我们会发现netty中很多方法的调用都是通过线程池的方式进行异步的调用, 这种  eventLoop.execute 方式的调用,实际上便是reactor线程.对应项目中使用广泛的NioE ...

  2. Netty学习三:线程模型

    1 Proactor和Reactor Proactor和Reactor是两种经典的多路复用I/O模型,主要用于在高并发.高吞吐量的环境中进行I/O处理. I/O多路复用机制都依赖于一个事件分发器,事件 ...

  3. Netty高性能之Reactor线程模型

    Netty是一个高性能.异步事件驱动的NIO框架,它提供了对TCP.UDP和文件传输的支持,作为一个异步NIO框架,Netty的所有IO操作都是异步非阻塞的,通过Future-Listener机制,用 ...

  4. Netty源码分析--Reactor模型(二)

    这一节和我一起开始正式的去研究Netty源码.在研究之前,我想先介绍一下Reactor模型. 我先分享两篇文献,大家可以自行下载学习.  链接:https://pan.baidu.com/s/1Uty ...

  5. Netty(三):线程模型

    Netty中支持单线程模型,多线程模型,主从多线程模型. 1 单线程模型 在ServerBootstrap调用方法group的时候,传递的参数是同一个线程组,且在构造线程组的时候,构造参数为1,这种开 ...

  6. Netty Reator(二)Scalable IO in Java

    Netty Reator(二)Scalable IO in Java Netty 系列目录 (https://www.cnblogs.com/binarylei/p/10117436.html) Do ...

  7. Reactor模型

    Reactor模型 原文地址:http://www.ivaneye.com/2016/07/23/iomodel.html 无处不在的C/S架构 在这个充斥着云的时代,我们使用的软件可以说99%都是C ...

  8. Netty(二) 从线程模型的角度看 Netty 为什么是高性能的?

    前言 在之前的 SpringBoot 整合长连接心跳机制 一文中认识了 Netty. 但其实只是能用,为什么要用 Netty?它有哪些优势?这些其实都不清楚. 本文就来从历史源头说道说道. 传统 IO ...

  9. Netty如何实现Reactor模式

    在前面的文章中(Reactor模型详解),我们讲解了Reactor模式的各种演变形式,本文主要讲解的则是Netty是如何实现Reactor模式的.这里关于Netty实现的Reactor模式,需要说明的 ...

随机推荐

  1. db2 性能查看top sql

    DB2 V10.3    查看top sql ,类似oracle 这篇文章是对之前有篇db2 v9的简化更新,总体还是觉得DB2TOP比较好用直观,不过需要导出SQL时,或自动化脚本时,还是建议执行S ...

  2. thymeleaf 处理模板为字符串

    @Autowired private SpringTemplateEngine thymeleaf; public String aa() { Context context = new Contex ...

  3. artTemplate/template.js模板将时间格式化为正常的日期

    网上提供的方法用不了 自己琢磨的 注意:ajax的异步方式必须设置成true才行,false不起作用.async: true: <script> function timestamp (v ...

  4. kafka消息队列的简单理解

    kafka在大数据.分布式架构中都很流行.kafka可以进行流式计算,也可以做为日志系统,还可以用于消息队列. 本篇主要是消息队列相关的知识. 零.kafka作为消息队列的优点: 分布式的系统 高吞吐 ...

  5. leetcode 栈和队列类型题

    1,Valid Parentheses bool isVaild1(string& s) { // 直接列举,不易扩展 stack<char> stk; ; i < s.le ...

  6. cf-Round551-Div2-D. Serval and Rooted Tree(DP)

    题目链接:https://codeforces.com/contest/1153/problem/D 题意:有一棵树,给定结点数n,在每个结点上的操作(max:表示该结点的number为其孩子结点中的 ...

  7. ceph luminous 新功能之内置dashboard 之 mgr功能模块配置

    前言 ceph luminous版本新增加了很多有意思的功能,这个也是一个长期支持版本,所以这些新功能的特性还是很值得期待的,从底层的存储改造,消息方式的改变,以及一些之前未实现的功能的完成,都让ce ...

  8. if (HttpContext.Current.User.Identity.IsAuthenticated) 权限验证总是true

    将浏览器关闭重启. 注:该语句是判断用户是否经过验证.

  9. 【Linux 线程】线程同步《三》

    1.条件变量 条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待"条件变量的条件成立"而挂起:另一个线程使"条件成立"(给出条 ...

  10. python学习-(__new__方法和单例模式)

    class Dog(object): __instance = None __init_flag = False def __new__(cls, name): if cls.__instance = ...