架构模式:pipeline

知名的 Pipeline 模式

  • unix 的 pipeline
cat helloworld.txt | grep "hello world" | rev | > output.txt

读取文本内容,并过滤 “hello world”,然后反转字符,将最终结果输出到 output.txt

  • Web 框架中间件
    Laravel 中的管道
    Laravel 在框架中很多地方都使用了管道,最常见的就是中间件实现。当请求最终到达控制器动作被处理前,会经过一系列的中间件。每个中间件都有一个独立的职责,例如,设置 Cookie / 判断是否登录以及阻止 CSRF 攻击等。

每个阶段都会对请求进行处理,如果请求通过就会被传递给下一个处理,不通过就会返回相应的 HTTP 响应。

其实何止是 Laravel,Python 中的 Django 同样如此。


struct.png

也就是说,每一个请求都是先通过中间件的 process_request 函数,这个函数返回 None 或者 HttpResponse 对象,如果返回前者,继续处理其他中间件,如果返回一个 HttpResponse,就处理终止,返回到页面上。Django 中把中间件叫做 hook(钩子)。

  • struct2


    struct2.png
  • 中间件,完整链路。所谓的中间件不就是 Pipeline 模式吗?

Pipeline 的特点

  • 管道就像一个流水线,把复杂的问题的解决方案分解成一个个处理单元,然后依次处理,前一个处理单元的结果也是第二个模块的输出。
  • 这些处理步骤通常会放在一个数组里,方便迭代这个数组时顺序执行

Pipeline 结构

  1. Pipeline的类模型由 Pipeline/ Valve/ Context 组成。Pipeline 代表执行流,
    Valve代表执行流中的一个节点,Context 是执行时的上下文信息,它一般由两部分组成:request/response + 当前流的执行状态。
  2. 有的系统只能有一个 Pipeline, 有的则允许配多个。在 Struct2 中,一个 interceptor 的组合,就代表一个 Pipeline;多种组合,意味着多个 Pipeline.

Pipeline 用法

  1. 有的 Pipeline 流是在同一个层次上,每个 valve 处理的 request / response 对象是同质的。比如 servlet filter 和各种 MVC 框架,所处理的事情都是 web 层,所处理的 context 对象就是 http request 或者框架自定义的 javabean。
  2. 有的 pipeline 流则是纵向的,从上层流到下层,或从下层流到上层,这时每个 valve 所处理的 request / response 对象一般是异构的。协议栈就是个典型的例子:下层 valve 处理字节流,上层处理字符流。不过,为了适应 pipeline 的架构,这些异构的 context 对象必须有共同的基类,并且把这个基类作为各个 valve 的输入参数。
  3. 从请求处理的角度来说,Pipeline 可以代表整个执行流,也可以用作请求被最终处理前的 Interceptor. Webx, netty 中的 Pipeline 会将最有一个 Valve 作为请求处理者(一般称为 Request Handler), 而 servlet filter 和 struct2 interceptor 只作为请求拦截、加工,真正处理请求的是 servlet 和 action

pipeline 程序流

  1. 一个完整的 Pipeline 执行流一般是一个环路:Valve1 => Valve2 => Valve3 => Valve2 => Valve1, 从拦截的角度讲,valve 既是前置拦截(下一个 valve 执行前),又是后置拦截(下一个 valve 执行后)
  2. 为了达到前后双拦截的目标,程序有两种方法。有一种是使用了 foreach 方法分别执行每个拦截器的前置拦截方法,然后又以相反的顺序分别执行每个拦截器的后置拦截方法。这种方法比较直观,Spring MVC Interceptor 就是这种。
  3. 主流的拦截做法,把一个 valve 的执行嵌套在前一个 valve 的执行里面;每个 valve 的执行会有一句"nextValve.invoke()", 然后在这句代码前后做一些拦截。这种方式有点费解,而且由于嵌套过多容易造成比较深的调用栈;不过它有一个好处:更方便地中断执行并处理异常。
  4. 执行流程必须提供中断机制和异常处理机制,比如鉴权 filter 发现用户未登录时需立即返回 403 并中断流,当一个 valve 出现异常时这个异常需要被捕捉、处理。如果 Valve 是嵌套执行的,这些机制会很方便实现:鉴权 filter 发现用户未登录,不调用 nextValue.invoke() 即可中断 pipeline;至于异常处理,Struct2 默认使用 ExceptionMappingInterceptor 作为 Pipeline 中的第一个 valve,它会把 nextIntercetpor.invoke() 放在自己 try/catch 中。如果 valve 不是嵌套执行,而是由pipeline 通过 forEach 编排执行的,那么这些非正常流的“扳道工”职责必须由 pipeline 自己来承担,这可能会使 pipeline 不够精简;如果来了新的逻辑(比如异步执行),又得改 pipeline,导致 pipeline 不太稳定。

pipeline 设计模式

一个 pipeline 结构可以做成一个单例,另外做一个 PipelineContext 代表 Pipeline 当前的执行流,至于 Valve,它相当于 stateless service 做成单例即可。

Pipeline 的优点

  • 对于每个处理单元又可以打补丁,做监听。(这就是切面编程了)
  • 这些处理步骤的代码还可以被其他不同的解决方案复用;
  • 在复杂进程中添加、移除和替换子任务非常轻松。

Pipeline 的使用场景

参考文件

http://www.chenjianjx.com/myblog/entry/%E5%85%B3%E4%BA%8Epipeline%E6%9E%B6%E6%9E%84%E7%9A%84%E5%87%A0%E7%82%B9%E8%AF%B4%E6%98%8E
http://blog.csdn.net/yanghua_kobe/article/details/7561016
http://blog.csdn.net/wangyangzhizhou/article/details/45441355,这个没有看懂例子。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,163评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,301评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,089评论 0 352
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,093评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,110评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,079评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,005评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,840评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,278评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,497评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,667评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,394评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,980评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,628评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,649评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,548评论 2 352

推荐阅读更多精彩内容

  • iOS网络架构讨论梳理整理中。。。 其实如果没有APIManager这一层是没法使用delegate的,毕竟多个单...
    yhtang阅读 5,188评论 1 23
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,651评论 18 139
  • 从三月份找实习到现在,面了一些公司,挂了不少,但最终还是拿到小米、百度、阿里、京东、新浪、CVTE、乐视家的研发岗...
    时芥蓝阅读 42,236评论 11 349
  • 姓名: 李小娜 [嵌牛导读]: SpringMVC 中的Interceptor 拦截器也是相当重要和相当有用的,...
    n184阅读 3,162评论 0 4
  • 最近雾霾天气很频繁,呼吸中肮脏的空气,受伤的肺有点不爽,我也想像着吹着海风,呼吸新鲜空气的清新感觉!那凉凉...
    67fbaec5208f阅读 413评论 0 0