SpringCloud源码| zuul源码

zuul主要使用责任链设计模式

其中有如下过滤器

pre过滤器

  • -3:ServletDetectionFilter
  • -2:Servlet30WrapperFilter
  • -1:FromBodyWrapperFilter
  • 1:DebugFilter
  • 5:PreDecorationFilter

routing过滤器

  • 10:RibbonRoutingFilter
  • 100:SimpleHostRoutingFilter
  • 500:SendForwardFilter

post过滤器

  • 0:SendErrorFilter
  • 900:LocationRewriteFilter
  • 1000:SendResponseFilter

@EnableZuulProxy为spring cloud中zuul的入口

1
2
3
4
5
6
7
@EnableCircuitBreaker
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(ZuulProxyMarkerConfiguration.class)
public @interface EnableZuulProxy {

}

然后在ZuulProxyAutoConfiguration进行相关类的注册

经过断点调试,核心逻辑为此方法ZuulServlet#service

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
@Override
public void service(javax.servlet.ServletRequest servletRequest, javax.servlet.ServletResponse servletResponse) throws ServletException, IOException {
    try {
        init((HttpServletRequest) servletRequest, (HttpServletResponse) servletResponse);

        // Marks this request as having passed through the "Zuul engine", as opposed to servlets
        // explicitly bound in web.xml, for which requests will not have the same data attached
        //从threadlocal中获取线程独有的RequestContext
        RequestContext context = RequestContext.getCurrentContext();
        context.setZuulEngineRan();
		
        //先执行pre过滤器
        try {
            preRoute();
        } catch (ZuulException e) {
            //若执行失败,则执行post过滤器 并返回
            error(e);
            postRoute();
            return;
        }
        //执行route过滤器
        try {
            route();
        } catch (ZuulException e) {
            //报错则执行post过滤器 并返回
            error(e);
            postRoute();
            return;
        }
        //若报错则再重试一遍
        try {
            postRoute();
        } catch (ZuulException e) {
            error(e);
            return;
        }

    } catch (Throwable e) {
        error(new ZuulException(e, 500, "UNHANDLED_EXCEPTION_" + e.getClass().getName()));
    } finally {
        //执行完毕之后,回收threadlocal中的context
        RequestContext.getCurrentContext().unset();
    }
}

大致的逻辑就是如此,因为在项目中暂时不准备使用zuul。详细源码以后再进行分析

Talk is cheap, show me the bug/code.
使用 Hugo 构建
主题 StackJimmy 设计