后端开发iOS开发之常用技术点java全栈

架构模式:pipeline

2018-03-21  本文已影响2046人  智勇双全的小六

知名的 Pipeline 模式

cat helloworld.txt | grep "hello world" | rev | > output.txt

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

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

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


struct.png

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

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,这个没有看懂例子。

上一篇下一篇

猜你喜欢

热点阅读