Pipeline(netty源码)
精进篇:netty源码死磕6
巧夺天工——Pipeline模式揭秘
1. 巧夺天工——Pipeline模式揭秘
1.1. Pipeline模式简介
管道的发名者叫,Malcolm Douglas McIlroy,他也是Unix的创建者,是Unix文化的缔造者之一。
40年前,Unix操作系统横空出世,Unix不仅仅带来了一个操作系统,还创造C语言,Socket,开源,黑客等等文化,这些文化影响着整个计算机世界的文明,直到今天。
如果说Unix是计算机文明中最伟大的发明,那么,Unix下的Pipe管道就是跟随Unix所带来的另一个伟大的发明。管道的出现,解决的就是让不同功能的程序可以互相连通通讯,从而可以让软件开发,程序开发更加的“高内聚,低耦合”,从而可以让程序“Do one thing, Do it well”,从而可以让程序“Keep it Simple Stupid”等等,这一哲学引影了一代又一代的软件架构,直到今天的云计算。
管道模型,是一种“链式模型”,用来串接不同的程序或者不同的组件,让它们组成一条直线的工作流。这样给定一个完整的输入,经过各个组件的先后协同处理,得到唯一的最终输出。
1.2. Pipeline模式应用场景
简单的说,管道模型的典型应用场景,可以用一个形象的比方,有点类似像富士康那么的工厂生产线。
管道模型包含两个部分:pipeline 管道、valve 阀门。
pipeline 管道,可以比作车间生产线,在这里可认为是容器的逻辑处理总线。
valve 阀门,可以比作生产线上的工人,负责完成各自的部分工作。 阀门也可以叫做Handler 处理者。
1.3. Tomcat中的Pipeline模式
在我们非常熟悉的Web容器Tomcat中,一个请求,首先被Connector接受到。然后,会将请求交给Container,Container处理完了之后将结果返回给Connector 。
Tomcat中,Container包含了Engine、Host、Context、Wrapper几个内部的子容器元素。
这几个子容器元素的功能,赘述如下:
Engine:代表一个完整的 Servlet 引擎,可以包含多个Host。它接收来自Connector的请求,并决定传给哪个Host来处理,得到Host处理完的结果后,返回给Connector。
Host:代表一个虚拟主机,一个Host能运行多个应用,它负责安装和展开这些应用,每个Host对应的一个域名。
Context:一个Context代表一个运行在Host上的Web应用
Wrapper: 一个Wrapper 代表一个 Servlet,它负责管理一个 Servlet,包括的 Servlet 的装载、初始化、执行以及资源回收。
在一个用户请求过来后,Tomcat中的每一级子容器,都对应于一个阀门Valve(注意:这个单词不是value,有一个字母的差别)。Tomcat接受请求之后,请求从被接受,被分发,被处理,到最后转变成http响应,会通过如下的阀门序列。
这些阀门(Valve)通过invoke(next)方法彼此串联起来,最终构成的执行顺序,构成一个管道。
Pipeline模式,在设计模式中,属于责任链模式的一种。在Tomcat的Pipeline模式中。从Engine到Host再到Context一直到Wrapper,都是通过同一个责任链,来传递请求。
1.4. Netty中的Pipeline模式
看完前面的《Netty 源码(ChannelHandler 死磕)》一文,大家对Netty的Pipeline已经有初步的了解。
这里再简单的回顾一下。
一个Channel,拥有一个ChannelPipeline,作为ChannelHandler的容器。
但是一个ChannelHandler,不能直接放进Pipeline中,必须包裹一个AbstractChannelHandlerContext 的上下文环境。
在初始化Netty的Channel时,需要将Handler加载到Pipeline中。
假定加载三个Handler,分别负责解码、业务、编码。三个Handler加载到ChannelPipeline的参考代码如下:
@Override
public void initChannel(SocketChannel ch) throws Exception
{
ChannelPipeline p = ch.pipeline();
p.addLast(new DecoderHandler());
p.addLast(new BusinessHandler());
p.addLast(new EncoderHandler());
}
Netty中Channel加完Hander之后,Pipeline的容器内容图如下:
Pipeline中不直接加入Handler,而是需要进行包裹。对应于Decoder、Business、Encoder三个Hander,分别创建三个默认的上下文包裹器(DefaultContext )。DefaultContext 的具体实现类,在Netty中,是DefaultChannelHandlerContext。
除此之外,Pipeline的头尾,各有一个特别的上下文Context 。这两个Hander Context ,不是默认的DefaultContext 。分别有自己的类型。
1.5. Context的类型
在Pipeline中头尾,分别各有一个特别的HandlerContext——简称Head和Tail。Head的类型是HeadContext。Tail的类型是TailContext。这两种类型,和DefaultChannelHandlerContext类型,都是AbstractChannelHandlerContext的子类。
Head和作用是什么呢?
Head上下文包裹器的主要作用: 主要是作为入站处理的起点。数据从Channel读入之后,一个入站数据包从Channel的事件发送出来,首先从Head开始,被后面的所有的入站处理器,逐个进行入站处理。
大致的入站流程如下图:
注意,TailContext,其实也是一个入站处理器。先按下不表,待会详细阐述。
Tail的作用是什么呢?
Tail上下文包裹器的主要作用: 主要是作为出站处理的起点。当所有的入站处理器,都处理完成后,开始出站流程。需要出站的数据包,首先从Tail开始,被所有的出站处理器上下文Context中的Hander逐个进行处理。然后将处理结果,写入Channel中。
注意,HeadContext,其实也是一个出站处理器。先按下不表,待会详细阐述。
Tail和Head内部,没有包裹其他的内部Handler成员。这一点,是与默认的上下文包裹器DefaultChannelHandlerContext不同的地方。
TailContext本身实现了ChannelInboundHandler 接口的方式,可以完成入站处理的操作,作为一个入站处理器使用。
HeadContext本身,实现了ChannelOutboundHandler 接口的方式,可以完成出站处理的操作,完成最终的出站处理操作。
1.6. Pipeline模式的优点:
总结一下Pipeline模式的优点,如下:
1、降低耦合度。它将请求的发送者和接收者解耦。
2、简化了Handler处理器。使得处理器不需要不需要知道链的结构。也就是Handler处理器可以是无状态的。与责任链(流水线)相关的状态,交给了Context去维护。
3、增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任。
4、 增加新的请求处理器很方便。
1.7. 小结
本节从宏观上,解读了什么是Netty的pipeline。
下一篇:Pipeline的入站流程和出站流程
Pipeline(netty源码)的更多相关文章
- Netty源码分析第4章(pipeline)---->第1节: pipeline的创建
Netty源码分析第四章: pipeline 概述: pipeline, 顾名思义, 就是管道的意思, 在netty中, 事件在pipeline中传输, 用户可以中断事件, 添加自己的事件处理逻辑, ...
- Netty源码分析第4章(pipeline)---->第2节: handler的添加
Netty源码分析第四章: pipeline 第二节: Handler的添加 添加handler, 我们以用户代码为例进行剖析: .childHandler(new ChannelInitialize ...
- Netty源码分析第4章(pipeline)---->第3节: handler的删除
Netty源码分析第四章: pipeline 第三节: handler的删除 上一小节我们学习了添加handler的逻辑操作, 这一小节我们学习删除handler的相关逻辑 如果用户在业务逻辑中进行c ...
- Netty源码分析第4章(pipeline)---->第4节: 传播inbound事件
Netty源码分析第四章: pipeline 第四节: 传播inbound事件 有关于inbound事件, 在概述中做过简单的介绍, 就是以自己为基准, 流向自己的事件, 比如最常见的channelR ...
- Netty源码分析第4章(pipeline)---->第5节: 传播outbound事件
Netty源码分析第五章: pipeline 第五节: 传播outBound事件 了解了inbound事件的传播过程, 对于学习outbound事件传输的流程, 也不会太困难 在我们业务代码中, 有可 ...
- Netty源码分析第4章(pipeline)---->第6节: 传播异常事件
Netty源码分析第四章: pipeline 第6节: 传播异常事件 讲完了inbound事件和outbound事件的传输流程, 这一小节剖析异常事件的传输流程 首先我们看一个最最简单的异常处理的场景 ...
- Netty源码分析第4章(pipeline)---->第7节: 前章节内容回顾
Netty源码分析第四章: pipeline 第七节: 前章节内容回顾 我们在第一章和第三章中, 遗留了很多有关事件传输的相关逻辑, 这里带大家一一回顾 首先看两个问题: 1.在客户端接入的时候, N ...
- Pipeline模式(netty源码死磕6)
精进篇:netty源码死磕6 巧夺天工--Pipeline模式揭秘 1. 巧夺天工--Pipeline模式揭秘 1.1. Pipeline模式简介 管道的发名者叫,Malcolm Douglas M ...
- Pipeline inbound(netty源码7)
netty源码死磕7 Pipeline 入站流程详解 1. Pipeline的入站流程 在讲解入站处理流程前,先脑补和铺垫一下两个知识点: (1)如何向Pipeline添加一个Handler节点 ( ...
随机推荐
- es6总结(二)--正则表达式和字符串
- 45深入理解C指针之---指针释放
一.size_t:用于安全表示长度,所有平台和系统都会解析成自己对应的长度 1.定义:size_t类型表示C中任何对象所能表示的最大长度,是个无符号整数:常常定义在stdio.h或stdlib.h中 ...
- py2exe使用方法 (含一些调试技巧,如压缩email 类)
http://justcoding.iteye.com/blog/900993 一.简介 py2exe是一个将python脚本转换成windows上的可独立执行的可执行程序(*.exe)的工具,这样, ...
- HDU 4405: Aeroplane chess
类型:概率DP 题意:一条直线下飞行棋,色子六个面等概率.同时存在一些飞机航线,到了某个点可以直接飞到后面的另一个点,可以连飞,保证一个点至多一条航线.求到达或者超过终点 所需要 掷色子的期望次数. ...
- MySQL 几种调式分析利器
目录 pstack gdb strace perf pstack 获取堆栈信息 问题线程的定位 负载较低 mysql_pid=4522 pstack $mysql_pid>pstack.info ...
- FZU 2224 An exciting GCD problem(GCD种类预处理+树状数组维护)同hdu5869
题目链接:http://acm.fzu.edu.cn/problem.php?pid=2224 同hdu5869 //#pragma comment(linker, "/STACK:1024 ...
- 正确使用Block避免Cycle Retain和Crash
Block简介 Block作为C语言的扩展,并不是高新技术,和其他语言的闭包或lambda表达式是一回事.需要注意的是由于Objective-C在iOS中不支持GC机制,使用Block必须自己管理内存 ...
- cocos2d-x step by step(3) Doub le Kill简单的一些小动画
在触控厮混了两年多,不过达到了自己的初衷以及目的. 目前从事cocos2d的更改和调优移植工作. 1 简单的一个图片放大和缩小 auto sprite = Sprite::create("l ...
- Samp免流软件以及地铁跑酷的自校验分析
[文章标题]:Samp免流软件以及地铁跑酷的自校验分析 [文章作者]: Ericky [作者博客]: http://blog.csdn.net/hk9259 [下载地址]: 自行百度 [保护方式]: ...
- com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown database 'user'
1.错误描写叙述 2014-7-12 21:06:05 com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource getPoolManager 信息: ...