spring-cloud-Zuul学习(三)【中级篇】--Filter链 工作原理与Zuul原生Filter【重新定义spring cloud实践】

这里开始记录zuul中级进阶内容。前面说过了,zuul主要是一层一层的Filter过滤器组成,并且Zuul的逻辑引擎与Filter可用其他基于JVM的语言编写,比如:Groovy。

  • 工作原理

Zuul的核心逻辑是由一系列紧密相连配合工作的Filter来实现,它们能够在进行HTTP请求的或者响应的时候执行相关操作。Zuul filter的主要特性有以下几点:

□ Filter的类型:决定了Filter在Filter链的执行顺序。可能是路由之前、路由之中、路由之后、路由异常时;

     □ Filter的执行顺序:同一种类型的Filter可以通过filterOrder()方法设置执行顺序。一般根据需求去设定;

□ Filter的执行条件:Filter运行时需要的标准或条件;

□ Filter的执行效果:产生的执行效果。

Zuul内部提供了一个动态读取、编译、运行这些Filter的机制。Filter之间不直接通信,在请求线程中通过RequestContext共享状态(用ThreadLocal实现),当然也可以在Filter之间使用ThreadLocal来收集自己需要的状态或数据。也就是使用RequestContext上下文。

  Zuul中不同类型Filter的执行逻辑在com.netflix.zuul.http.ZuulServlet定义,相关代码:

 1 @Override
 2     public void service(javax.servlet.ServletRequest servletRequest, javax.servlet.ServletResponse servletResponse) throws ServletException, IOException {
 3         try {
 4             init((HttpServletRequest) servletRequest, (HttpServletResponse) servletResponse);
 5 
 6             // Marks this request as having passed through the "Zuul engine", as opposed to servlets
 7             // explicitly bound in web.xml, for which requests will not have the same data attached
 8             RequestContext context = RequestContext.getCurrentContext();
 9             context.setZuulEngineRan();
10 
11             try {
12                 preRoute();
13             } catch (ZuulException e) {
14                 error(e);
15                 postRoute();
16                 return;
17             }
18             try {
19                 route();
20             } catch (ZuulException e) {
21                 error(e);
22                 postRoute();
23                 return;
24             }
25             try {
26                 postRoute();
27             } catch (ZuulException e) {
28                 error(e);
29                 return;
30             }
31 
32         } catch (Throwable e) {
33             error(new ZuulException(e, 500, "UNHANDLED_EXCEPTION_" + e.getClass().getName()));
34         } finally {
35             RequestContext.getCurrentContext().unset();
36         }
37     }

这些代码其实就能看出整个请求的执行顺序了。待会后面你就会发现这个顺序。

  •  Zuul总共有四种不同的生命周期类型的Filter:

pre:  在路由下级服务之前执行;比如鉴权、限流都是需要在此类Filter执行。

route:这类Filter是Zuul路由动作的执行者,是Apache HTTPClient或Netflix Ribbon构建和发送原始Http请求的地方,目前已支持OKHTTP。

post:这类Filter是源服务返回结果或发生异常信息发生后执行的;需要对返回信息做一些处理,可以在此类Filter处理。

error:在整个生命周期内如果发生异常,则会进入error Filter,可做全局异常处理。

实际开发中经常会根据需求,然后自定义实现以上类型的FIlter。在Filter之中,通过com.netflix.zuul.context。RequestContext类进行通讯,内部采用ThreadLocal保存每个请求的一些信息,包括请求路由、错误信息、HttpServletRequest、HTTPServletResponse,它还扩展了ConcurrentHashMap,目的是为了在处理过程中保存任何形式的信息。

 

  • 禁用原生Filter:zuul.<SimpleClassName>.<filterType>.disable=true
posted @ 2019-04-28 10:08  像灭霸一样看日出  阅读(383)  评论(0编辑  收藏  举报