Netty源代码学习——ChannelPipeline模型分析

简介:
參考Netty API
io. netty. channel.ChannelPipeline

A list of ChannelHandlers which handles or intercepts inbound events and outbount operations of aChannel.ChannelPipeline implements an advanced form of theIntercepting Filter pattern to give a user full control over how an event is handled and how theChannelHandlers in a pipeline interact with each other.

Creation of a pipeline

Each channel has its own pipeline and it is created automatically when a new channel is created.

How an event flows in a pipeline

The following diagram describes how I/O events are processed by ChannelHandlers in aChannelPipeline typically. An I/O event is handled by either aChannelInboundHandler or aChannelOutboundHandler and be forwarded to its closest handler by calling the event propagation methods defined inChannelHandlerContext, such asChannelHandlerContext.fireChannelRead(Object) andChannelHandlerContext.write(Object).

                                                 I/O Request
                                            via Channel or
                                        ChannelHandlerContext
                                                      |
  +---------------------------------------------------+---------------+
  |                           ChannelPipeline         |               |
  |                                                  \|/              |
  |    +---------------------+            +-----------+----------+    |
  |    | Inbound Handler  N  |            | Outbound Handler  1  |    |
  |    +----------+----------+            +-----------+----------+    |
  |              /|\                                  |               |
  |               |                                  \|/              |
  |    +----------+----------+            +-----------+----------+    |
  |    | Inbound Handler N-1 |            | Outbound Handler  2  |    |
  |    +----------+----------+            +-----------+----------+    |
  |              /|\                                  .               |
  |               .                                   .               |
  | ChannelHandlerContext.fireIN_EVT() ChannelHandlerContext.OUT_EVT()|
  |        [ method call]                       [method call]         |
  |               .                                   .               |
  |               .                                  \|/              |
  |    +----------+----------+            +-----------+----------+    |
  |    | Inbound Handler  2  |            | Outbound Handler M-1 |    |
  |    +----------+----------+            +-----------+----------+    |
  |              /|\                                  |               |
  |               |                                  \|/              |
  |    +----------+----------+            +-----------+----------+    |
  |    | Inbound Handler  1  |            | Outbound Handler  M  |    |
  |    +----------+----------+            +-----------+----------+    |
  |              /|\                                  |               |
  +---------------+-----------------------------------+---------------+
                  |                                  \|/
  +---------------+-----------------------------------+---------------+
  |               |                                   |               |
  |       [ Socket.read() ]                    [ Socket.write() ]     |
  |                                                                   |
  |  Netty Internal I/O Threads (Transport Implementation)            |
  +-------------------------------------------------------------------+
 


                                                                                                                                  Figure 1

An inbound event is handled by the inbound handlers in the bottom-up direction as shown on the left side of the diagram. An inbound handler usually handles the inbound data generated by the I/O thread on the bottom of the diagram. The inbound data is often read from a remote peer via the actual input operation such as SocketChannel.read(ByteBuffer). If an inbound event goes beyond the top inbound handler, it is discarded silently, or logged if it needs your attention.

An outbound event is handled by the outbound handler in the top-down direction as shown on the right side of the diagram. An outbound handler usually generates or transforms the outbound traffic such as write requests. If an outbound event goes beyond the bottom outbound handler, it is handled by an I/O thread associated with the Channel. The I/O thread often performs the actual output operation such asSocketChannel.write(ByteBuffer).

For example, let us assume that we created the following pipeline:

 ChannelPipeline p = ...;
 p.addLast("1", new InboundHandlerA());
 p.addLast("2", new InboundHandlerB());
 p.addLast("3", new OutboundHandlerA());
 p.addLast("4", new OutboundHandlerB());
 p.addLast("5", new InboundOutboundHandlerX());
 
In the example above, the class whose name starts with  Inbound  means it is an inbound handler. The class whose name starts with Outbound  means it is a outbound handler.

In the given example configuration, the handler evaluation order is 1, 2, 3, 4, 5 when an event goes inbound. When an event goes outbound, the order is 5, 4, 3, 2, 1. On top of this principle,ChannelPipeline skips the evaluation of certain handlers to shorten the stack depth:

Forwarding an event to the next handler

As you might noticed in the diagram shows, a handler has to invoke the event propagation methods in ChannelHandlerContext  to forward an event to its next handler. Those methods include: and the following example shows how the event propagation is usually done:
 public class MyInboundHandler extends ChannelInboundHandlerAdapter {
     @Override
     public void channelActive(ChannelHandlerContext ctx) {
         System.out.println("Connected!");
         ctx.fireChannelActive();
     }
 }

 public clas MyOutboundHandler extends ChannelOutboundHandlerAdapter {
     @Override
     public void close(ChannelHandlerContext ctx, ChannelPromise promise) {
         System.out.println("Closing ..");
         ctx.close(promise);
     }
 }
 

Building a pipeline

A user is supposed to have one or more ChannelHandlers in a pipeline to receive I/O events (e.g. read) and to request I/O operations (e.g. write and close). For example, a typical server will have the following handlers in each channel's pipeline, but your mileage may vary depending on the complexity and characteristics of the protocol and business logic:

  1. Protocol Decoder - translates binary data (e.g. ByteBuf) into a Java object.
  2. Protocol Encoder - translates a Java object into binary data.
  3. Business Logic Handler - performs the actual business logic (e.g. database access).
and it could be represented as shown in the following example:
 static final EventExecutorGroup group = new DefaultEventExecutorGroup(16);
 ...

 ChannelPipeline pipeline = ch.pipeline();

 pipeline.addLast("decoder", new MyProtocolDecoder());
 pipeline.addLast("encoder", new MyProtocolEncoder());

 // Tell the pipeline to run MyBusinessLogicHandler's event handler methods
 // in a different thread than an I/O thread so that the I/O thread is not blocked by
 // a time-consuming task.
 // If your business logic is fully asynchronous or finished very quickly, you don't
 // need to specify a group.
 pipeline.addLast(group, "handler", new MyBusinessLogicHandler());
 

Thread safety

ChannelHandler can be added or removed at any time because aChannelPipeline is thread safe. For example, you can insert an encryption handler when sensitive information is about to be exchanged, and remove it after the exchange.

—————>>>>>>>>>>>>>>>>>>华丽的分界线<<<<<<<<<<<<<<<<<—————————————

Figure1 变形:

  
  +-------------------------------------------------------------------+
  |                                IN                                 |
  |                                 |                                 |
  |                                 |                                 |
  |                          [(Socket)read]                           |
  |                                 |                                 |
  |                                 |                                 |
  |                                \|/                                |
  |                      +----------+----------+                      |
  |                      | Inbound Handler  1  |                      |
  |                      +----------+----------+                      |
  |                                 |                                 |
  |                                \|/                                |
  |                      +----------+----------+                      |
  |                      | Inbound Handler  2  |                      |
  |                      +----------+----------+                      |
  |                                 .                                 |
  |                                 .                                 |
  |                                \./                                |
  |                   ChannelHandlerContext.FireIN_EVT                |       
  |                           [ method call]                          |
  |                                 .                                 |
  |                                 .                                 |
  |                                \./                                |    
  |                      +----------+----------+                      |
  |                      | Inbound Handler N-1 |                      |
  |                      +----------+----------+                      |
  |                                \|/                                |                                                                                                               
  |                                 |                                 |
  |                      +----------+----------+                      |
  |                      | Inbound Handler  N  |                      |
  |                      +----------+----------+                      |
  |                                 |                                 |
  |                                \|/                                |
  |                                 |                                 |
  +---------------------------------+---------------------------------+
  |                                 |                                 |
  |                                 |                                 |
  |                            Application                            |
  |                                 |                                 |
  |                                 |                                 |
  +---------------------------------+---------------------------------+
  |                                 |                                 |
  |                                \|/                                |
  |                     +-----------+----------+                      |
  |                     | Outbound Handler  1  |                      |
  |                     +-----------+----------+                      |
  |                                 |                                 |
  |                                \|/                  
  |                     +-----------+----------+                      |
  |                     | Outbound Handler  2  |                      |
  |                     +-----------+----------+                      |
  |                                 .                                 |
  |                                 .                                 |
  |                                \./                                |
  |                   ChannelHandlerContext.OUT_EVT()                 |
  |                           [ method call]                          |
  |                                 .                                 |
  |                                 .                                 |
  |                                \./                                | 
  |                     +-----------+----------+                      |
  |                     | Outbound Handler M-1 |                      |
  |                     +-----------+----------+                      |
  |                                 |                                 |
  |                                \|/                                |
  |                     +-----------+----------+                      |
  |                     | Outbound Handler  M  |                      |
  |                     +-----------+----------+                      |
  |                                 |                                 |
  |                                \|/                                |
  |                          [(Socket)write]                          |
  |                                 |                                 |
  |                                 |                                 |
  |                                \|/                                |
  |                                 |                                 |
  |                                OUT                                |
  +---------------+-----------------------------------+---------------+
 

责任链模式:

在阎宏博士的《JAVA与模式》一书中开头是这样描写叙述责任链(Chain of Responsibility)模式的:

  责任链模式是一种对象的行为模式。在责任链模式里,非常多对象由每个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的client并不知道链上的哪一个对象终于处理这个请求,这使得系统能够在不影响client的情况下动态地又一次组织和分配责任。

责任链模式涉及到的角色例如以下所看到的:

  ●  抽象处理者(Handler)角色:定义出一个处理请求的接口。假设须要,接口能够定义 出一个方法以设定和返回对下家的引用。这个角色通常由一个Java抽象类或者Java接口实现。

上图中Handler类的聚合关系给出了详细子类对下家的引用,抽象方法handleRequest()规范了子类处理请求的操作。

  ●  详细处理者(ConcreteHandler)角色:详细处理者接到请求后。能够选择将请求处理掉,或者将请求传给下家。

因为详细处理者持有对下家的引用,因此,假设须要,详细处理者能够訪问下家。

Java website development中的filter也是责任链模式。

參考文章:http://www.cnblogs.com/java-my-life/archive/2012/05/28/2516865.html。





本文转自mfrbuaa博客园博客,原文链接:http://www.cnblogs.com/mfrbuaa/p/5155112.html,如需转载请自行联系原作者

相关文章
|
8月前
|
Java
【Netty 网络通信】Netty 工作流程分析
【1月更文挑战第9天】Netty 工作流程分析
|
8月前
|
Java Unix Linux
【Netty技术专题】「原理分析系列」Netty强大特性之Native transports扩展开发实战
当涉及到网络通信和高性能的Java应用程序时,Netty是一个强大的框架。它提供了许多功能和组件,其中之一是JNI传输。JNI传输是Netty的一个特性,它为特定平台提供了高效的网络传输。 在本文中,我们将深入探讨Netty提供的特定平台的JNI传输功能,分析其优势和适用场景。我们将介绍每个特定平台的JNI传输,并讨论其性能、可靠性和可扩展性。通过了解这些特定平台的JNI传输,您将能够更好地选择和配置适合您应用程序需求的网络传输方式,以实现最佳的性能和可靠性。
153 7
【Netty技术专题】「原理分析系列」Netty强大特性之Native transports扩展开发实战
|
5月前
|
编解码 网络协议 API
Netty运行原理问题之Netty的主次Reactor多线程模型工作的问题如何解决
Netty运行原理问题之Netty的主次Reactor多线程模型工作的问题如何解决
|
4月前
|
存储 机器人 Linux
Netty(二)-服务端网络编程常见网络IO模型讲解
Netty(二)-服务端网络编程常见网络IO模型讲解
|
8月前
|
消息中间件 监控 Java
滴滴面试:谈谈你对Netty线程模型的理解?
Netty 线程模型是指 Netty 框架为了提供高性能、高并发的网络通信,而设计的管理和利用线程的策略和机制。 **Netty 线程模型被称为 Reactor(响应式)模型/模式,它是基于 NIO 多路复用模型的一种升级,它的核心思想是将 IO 事件和业务处理进行分离,使用一个或多个线程来执行任务的一种机制。** ## 1.**Reactor三大组件** Reactor 包含以下三大组件: ![image.png](https://cdn.nlark.com/yuque/0/2024/png/92791/1717079218890-89000a00-48bc-4a1a-b87e-e1b6
79 2
netty的异常分析 IllegalReferenceCountException refCnt: 0, decrement: 1
netty的异常分析 IllegalReferenceCountException refCnt: 0, decrement: 1
269 0
|
8月前
|
前端开发 网络协议 Java
Netty | 工作流程图分析 & 核心组件说明 & 代码案例实践
Netty | 工作流程图分析 & 核心组件说明 & 代码案例实践
441 0
|
8月前
|
开发工具 git
网络编程(三)netty学习demo和笔记和推荐的4本书
网络编程(三)netty学习demo和笔记和推荐的4本书
142 0
|
8月前
|
存储 网络协议 Java
Netty应用实例学习
Netty应用实例学习
58 0
|
8月前
|
编解码 缓存 网络协议
Netty核心功能学习
Netty核心功能学习
63 0