Netty责任链Pipeline详解

  • 小编 发布于 2019-11-18 01:35:33
  • 栏目:科技
  • 来源:IT人故事会
  • 5567 人围观

一起说说Netty责任链,责任链这块是netty运行机制的核心,一起来完整的了解下netty的责任链。

Netty责任链Pipeline详解

(一)责任链模式

  • ① 介绍

责任链模式(Chain of Responsibility Pattern) 为请求创建了一个处理对象的链。一个请求过来后,就交给一个责任链进行调用。在责任链里面定义很多很多的handler,具体请求这个程序的handler,请求者不关心,多少个步骤,多少次,只负责发送到责任链上,请求传递的细节不关心。

  • ② 实现责任链模式

处理器抽象类,具体的处理器实现类,保存处理器信息,处理执行。

Netty责任链Pipeline详解

  • ③ 源码分析
// -----链表形式调用------netty就是类似的这种形式
public class PipelineDemo {
 /**
 * 初始化的时候造一个head,作为责任链的开始,但是并没有具体的处理
 */
 public HandlerChainContext head = new HandlerChainContext(new AbstractHandler() {
 @Override
 void doHandler(HandlerChainContext handlerChainContext, Object arg0) {
 handlerChainContext.runNext(arg0);
 }
 });

 public void requestProcess(Object arg0) {
 this.head.handler(arg0);
 }

 public void addLast(AbstractHandler handler) {
 HandlerChainContext context = head;
 while (context.next != null) {
 context = context.next;
 }
 context.next = new HandlerChainContext(handler);
 }


 public static void main(String[] args) {
 PipelineDemo pipelineChainDemo = new PipelineDemo();
 pipelineChainDemo.addLast(new Handler2());
 pipelineChainDemo.addLast(new Handler1());
 pipelineChainDemo.addLast(new Handler1());
 pipelineChainDemo.addLast(new Handler2());

 // 发起请求
 pipelineChainDemo.requestProcess("火车呜呜呜~~");

 }
}

/**
 * handler上下文,我主要负责维护链,和链的执行
 */
class HandlerChainContext {
 HandlerChainContext next; // 下一个节点
 AbstractHandler handler;

 public HandlerChainContext(AbstractHandler handler) {
 this.handler = handler;
 }

 void handler(Object arg0) {
 this.handler.doHandler(this, arg0);
 }

 /**
 * 继续执行下一个
 */
 void runNext(Object arg0) {
 if (this.next != null) {
 this.next.handler(arg0);
 }
 }
}

// 处理器抽象类
abstract class AbstractHandler {
 /**
 * 处理器,这个处理器就做一件事情,在传入的字符串中增加一个尾巴..
 */
 abstract void doHandler(HandlerChainContext handlerChainContext, Object arg0); // handler方法
}

// 处理器具体实现类
class Handler1 extends AbstractHandler {
 @Override
 void doHandler(HandlerChainContext handlerChainContext, Object arg0) {
 arg0 = arg0.toString() + "..handler1的小尾巴.....";
 System.out.println("我是Handler1的实例,我在处理:" + arg0);
 // 继续执行下一个
 handlerChainContext.runNext(arg0);
 }
}

// 处理器具体实现类
class Handler2 extends AbstractHandler {
 @Override
 void doHandler(HandlerChainContext handlerChainContext, Object arg0) {
 arg0 = arg0.toString() + "..handler2的小尾巴.....";
 System.out.println("我是Handler2的实例,我在处理:" + arg0);
 // 继续执行下一个
 handlerChainContext.runNext(arg0);
 }
}

Netty责任链Pipeline详解

(二)Netty中的ChannelPipeline责任链

  • ① 介绍

pipeline管道保存了通道所有处理器信息,创建channel时自动创建一个专有的pipeline,入站事件和出站事件会调用pipeline上的处理器。

Netty责任链Pipeline详解

  • ② 入站事件和出站事件

入站事件:通常指IO线程生成了入站数据

(通俗理解:从socket底层自己往上冒上来的事件都是入站)
比如EventLoop收到selector的OP_READ事件,入站处理器调用socketChannel.read(ByteBuffer)接受到数据后,这将导致通道的ChannelPipeline中包含的下一个中的channelRead方法被调用

出站事件:通常指IO线程执行实际的输出操作

(通俗理解:想主动往socket底层操作的事件的都是出站)
比如bind方法用意时请求server socket绑定到给定的SocketAddress,这将导致通道的ChannelPipeline中包含的下一个出站处理器中的bind方法被调用

  • ③ Nettty中定义的事件
Netty责任链Pipeline详解

  • ④ Pipeline中的handler是什么

ChannelHeadler

用于处理I/O事件或者拦截I/O操作,并转发到ChannelPipeline中下一个处理器。这个顶级接口定义功能很弱,实际使用时会去实现下面两大子接口:处理入站I/O事件的ChannelInboundHandler、处理出站I/O操作的ChannelOutboundHandler

适配器类

为了方便开发,避免所有handler去实现一遍接口方法,Netty提供了简单的实现类:
ChannelInboundHandlerAdapter处理入站I/O事件
ChannelOutboundHandlerAdapter处理出站I/O事件
ChannelDuplexHandler支持同时处理入站和出站事件

ChannelHandlerContext

实际存储在Pipeline中的并非是ChannelHandler,而是上下文对象。将Handler包裹在上下文对象中,通过上下文对象与它所属的ChannelPipeline交互,向上或向下传递事件或者修改pipeline都是通过上下文对象。

  • ⑤ 那么如何维护Pipeline中的handler呢

ChannelPipeline是线程安全的,ChannelHandler可以在任何时候添加或者删除。例如你可以在即将交换敏感信息时插入加密处理程序,并在交换后删除它。一般操作,初始化的时候增加进去,较少删除。下面是Pipeline中管理的API

Netty责任链Pipeline详解

Netty责任链Pipeline详解

Netty责任链Pipeline详解

除了register方法还有bind方法,bind方法时出站事件执行顺序和入站事件相反

Netty责任链Pipeline详解

请求过来以后又是如何处理的呢?我们通过Accept事件获取请求,所以我们应该去看accept入站事件是如何处理的,

Netty责任链Pipeline详解

PS:用户在管道中有一个或者多个channelhandler来接收I/O事件(例如读取)和请求I/O操作(例如写入和关闭)一个典型的服务器在每个通道的管道中都有以下处理程序,但是根据协议和业务逻辑的复杂性和特征,可能会有所不同。
协议解码器--将二进制数据(例如ByteBuf)转换为Java对象
协议编码器--将java对象转化为二进制数据
业务逻辑处理程序--执行实际的业务逻辑(例如访问数据库)

转载请说明出处:866热点网 ©