Netty 使用异步事件驱动(Asynchronous Event-Driven)的应用程序范式,因此数据处理的管道(ChannelPipeLine)是经过处理程序(ChannelHandler)的事件链。事件和处理程序可以与入站和出站数据流相关。入站事件可以是以下各项:

  • 通道激活和停用
  • 读取操作事件
  • 异常事件
  • 用户事件

  出站事件更简单,通常与打开/关闭连接以及写入/刷新数据有关。

事件驱动模型

  事件驱动是指在持续事务管理过程中,进行决策的一种策略,即跟随当前时间点上出现的事件,调动可用资源,执行相关任务,使不断出现的问题得以解决,防止事务堆积。在计算机编程、公共关系、经济活动等领域均有应用。

  Netty 是一个异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端。

  轮询方式

  线程不断轮询访问相关事件发生源有没有发生事件,有发生事件就调用事件处理逻辑。

  事件驱动方式

  事件发生时主线程把事件放入事件队列,在另外线程不断循环消费事件列表中的事件,调用事件对应的处理逻辑处理事件。事件驱动方式也被称为消息通知方式,其实是设计模式中观察者模式的思路。

(图来源于网络)

  主要包括4个基本组件:

  事件队列(event queue):接收事件的入口,存储待处理事件

  分发器(event mediator):将不同的事件分发到不同的业务逻辑单元

  事件通道(event channel):分发器与处理器之间的联系渠道

  事件处理器(event processor):实现业务逻辑,处理完成后会发出事件,触发下一步操作

  

  可以看到,相对传统轮询模式,事件驱动有如下优点:

  • 可扩展性好,分布式的异步架构,事件处理器之间高度解耦,可以方便扩展事件处理逻辑
  • 高性能,基于队列暂存事件,能方便并行异步处理事件

ChannelHandler

  Channelhandler 处理一个 I / O 事件或拦截一个 I / O 操作,并将其转发给它的下一个处理程序。其主要的 Channelhandler 主要的子类型有 ChannelInboundHandler(处理入站 I / O事件,会添加状态更改的回调,使用户可以轻松连接到状态更改)和 ChannelOutboundHandler(处理出站 I / O 操作,是将收到有关 I / O 出站操作的通知的 ChannelHandler)。

  ChannelInboundHandler 当接收到数据或者与之关联的 Channel 状态改变时调用。

  ChannelOutboundHandler 提供了出站操作时调用的方法。这些方法会被 Channel,ChannelPipeline 和 ChannelHandlerContext 调用。ChannelOutboundHandler另一个一个强大的方面是它具有在请求时延迟操作或事件的能力。

  

(Netty ChannelHander 类图)

  ChannelHandler 应该和 ChannelHandlerContext 一起使用。ChannelHandler 应该通过上下文对象 ChannelHandlerContext管道 ChannelPipeline进行交互。使用上下文对象,ChannelHandler 可以将事件传递给上游或下游,通过特定于处理 Handler 使用 AttributeKeys 动态修改管道或存储信息。

 

  ChannelHandler 适配器

  Netty 提供了一个简单的 ChannelHandler 框架实现,给所有声明方法签名。这个类 ChannelHandlerAdapter 的方法,主要推送事件到 pipeline 下个 ChannelHandler 直到 pipeline 的结束。这个类 也作为 ChannelInboundHandlerAdapter 和ChannelOutboundHandlerAdapter 的基础。所有三个适配器类的目的是作为自己的实现的起点。您可以扩展它们,覆盖你需要自定义的方法。

  • ChannelInboundHandlerAdapter(ChannelInboundHandler实现)只是将操作转发到 ChannelPipeline 中的下一个 ChannelHandler。其子类可能会覆盖方法实现以对此进行更改。

  • ChannelOutboundHandlerAdapter(ChannelOutboundHandler实现)只通过ChannelHandlerContext转发每个方法调用。

  • ChannelDuplexHandler 表示 ChannelInboundHandler 和 ChannelOutboundHandler 中的组合。

  

  ChannelHandler 定义的生命周期操作如下表:

方法 描述
handlerAdded 当ChannelHandler添加到ChannelPipeline调用
handlerRemoved 当ChannelHandler从ChannelPipeline可移除时调用
exceptionCaught 当ChannelPipeline执行发生错误时调用

  当 ChannelHandler 添加到 ChannelPipeline,或者从 ChannelPipeline 移除后,这些将会调用。每个方法都会带 ChannelHandlerContext 参数。

  在状态管理方面 ChannelHandler通常需要存储一些状态信息。

  1)最简单推荐的方法是使用成员变量;

  2)尽管建议使用成员变量来存储处理程序的状态,但是由于某些原因,您可能不想创建许多处理程序实例。在这种情况下,可以使用 ChannelHandlerContext 提供的 AttributeKey;其中的 ChannelHandler 带有@Sharable注释,则意味着你可以只创建一次处理程序实例,然后将其多次添加到一个或多个?ChannelPipeline 中,而无需竞争条件。

参考:《Netty In Action》,Netty背后的事件驱动机制

Netty:Netty的介绍以及它的核心组件(三)—— 事件和ChannelHandler的更多相关文章

  1. Netty:Netty的介绍以及它的核心组件(一)—— Channel

    1. Netty 介绍 Netty 是一个无阻塞的输入/输出(NIO)框架,它使开发低级网络服务器和客户端变得相对简单.Netty为需要在套接字级别上工作的开发人员提供了令人难以置信的强大功能,例如, ...

  2. Netty:Netty的介绍以及它的核心组件(二)—— ChannelFuture与回调

    Callback 回调 一个 Callback(回调)就是一个方法,一个提供给另一个的方法的引用. 这让另一个方法可以在适当的时候回过头来调用这个 callback 方法.Callback 在很多编程 ...

  3. Netty重要概念介绍

    Netty重要概念介绍 Bootstrap Netty应用程序通过设置bootstrap(引导)类开始,该类提供了一个用于网络成配置的容器. 一种是用于客户端的Bootstrap 一种是用于服务端的S ...

  4. netty05(netty的一些介绍)

    netty的一些理论 netty是一个异步事件驱动的网络应用框架(NIO框架),所有IO操作都是异步非阻塞的,NIO是对IO的一个补充 用于开发客户端和服务器的通信(TCP/UDP)长短连接 nett ...

  5. [Netty] - Netty IN ACTION(导言)

    最近没什么事儿做,刚好看到有需要网络编程的知识,java中有NIO和IO两种不同的方式,但是NIO的编写比较麻烦,刚好找到一个成熟的网络框架Netty.接下来的一个月就准备将Netty IN ACTI ...

  6. Lucene.Net 2.3.1开发介绍 —— 四、搜索(三)

    原文:Lucene.Net 2.3.1开发介绍 -- 四.搜索(三) Lucene有表达式就有运算符,而运算符使用起来确实很方便,但另外一个问题来了. 代码 4.3.4.1 Analyzer anal ...

  7. Lucene.Net 2.3.1开发介绍 —— 二、分词(三)

    原文:Lucene.Net 2.3.1开发介绍 -- 二.分词(三) 1.3 分词器结构 1.3.1 分词器整体结构 从1.2节的分析,终于做到了管中窥豹,现在在Lucene.Net项目中添加一个类关 ...

  8. MySQL行(记录)的详细操作一 介绍 二 插入数据INSERT 三 更新数据UPDATE 四 删除数据DELETE 五 查询数据SELECT 六 权限管理

    MySQL行(记录)的详细操作 阅读目录 一 介绍 二 插入数据INSERT 三 更新数据UPDATE 四 删除数据DELETE 五 查询数据SELECT 六 权限管理 一 介绍 MySQL数据操作: ...

  9. Netty——基本使用介绍

    https://blog.csdn.net/haoyuyang/article/details/53243785 1.为什么选择Netty 上一篇文章我们已经了解了Socket通信(IO/NIO/AI ...

随机推荐

  1. 如何在云效流水线 Flow中构建属于自己的NPM仓库

    如何在云效流水线 Flow中构建属于自己的NPM仓库,Flow 通过各种构建组件,对各种语言提供了制品打包能力,让用户可以快速的使用流水线构建制品,并通过后续的部署任务进行部署.Flow 已经完成了与 ...

  2. c# 扩展方法奇思妙用基础篇九:Expression 扩展

    http://www.cnblogs.com/ldp615/archive/2011/09/15/expression-extension-methods.html .net 中创建 Expressi ...

  3. django框架开发流程

    python开发没有按目录划分,不像其它语言要先建一个包文件,所以python有必要先新建一个虚拟环境.这样不同的项目所依赖的环境和插件互不影响.虚拟环境的方法很多,这儿先用   virtualenv ...

  4. html 表单input disabled属性提交后台无法获得数据

    在input上加入disabled属性后, 点击提交会遗漏该值, 有两个办法: 一 可以考虑readonly属性,一样的不可修改操作,但是可以提交 二 在提交时 js 代码操作去除input上的dis ...

  5. Linux系列(32) - rpm命令管理之RPM查询(4)

    RPM包默认安装位置 RPM包默认安装路径 /etc/ 配置文件安装目录 /usr/bin/ 可执行的命令安装目录 /usr/lib/ 程序所使用的函数库保存位置 /usr/share/doc/ 基本 ...

  6. java面向对象编程(上)

    java面向对象学习的三条主线 1.Java类及类的成员:属性.方法.构造器.代码块.内部类 2.面向对象的三大特征:封装性.继承性.多态性.(抽象性) 3.其它关键字:this.super.stat ...

  7. 深入剖析 Laravel 服务容器

    https://cloud.tencent.com/developer/article/1340400

  8. 《exe应用程序UI自动化》

    前言:有很多公司做一些客户端的应用,每次发版都要耗费人力去手动回归比较费时,那么我们就想着去怎么去驱动人为的操作变为机器的操作过程,当然想着进行UI自动 那么我们就要考虑怎么去实现exe应用程序的自动 ...

  9. MyBatis-Plus代码生成器的使用

    1.MyBatis-Plus简介 ​ 在代码开发中,肯定会遇到代码中对应数据库表去编写实体类的工作,若数据库表数量多的情况下,编写Entity,属实是一件消耗时间,且并没有什么技术含量的事情,如何解决 ...

  10. 鸿蒙内核源码分析(CPU篇) | 整个内核就是一个死循环 | 祝新的一年牛气冲天 ! | v32.02

    百篇博客系列篇.本篇为: v32.xx 鸿蒙内核源码分析(CPU篇) | 整个内核就是一个死循环 | 51.c.h .o 任务管理相关篇为: v03.xx 鸿蒙内核源码分析(时钟任务篇) | 触发调度 ...