Netty:Netty的介绍以及它的核心组件(三)—— 事件和ChannelHandler

  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背后的事件驱动机制

原文地址:https://www.cnblogs.com/magic-sea/p/12797022.html