zoukankan      html  css  js  c++  java
  • Zuul【工作原理】

    zuul的核心逻辑都是由一系列filter过滤器链实现的,但是filter的类型不同,执行的时机也不同,效果自然也不一样,主要特点如下:

    1. filter的类型:filter的类型,决定了它在整个filter链中的执行顺序,可能在端点路由前执行,也可能在端点路由时执行,还有可能在端点路由后执行,甚至是端点路由发生异常时执行。
    2. filter的执行顺序:同一种类型的filter,可以通过filterOrder()方法设置执行顺序,一般都是根据业务场景自定义filter执行顺序。
    3. filter执行条件:filter运行所需的标准,或条件。
    4. filter执行效果:符合某个filter执行条件,产生执行效果。

    zuul内部有一套完整的机制,可以动态读取编译运行filter机制,filter与filter之间不直接通信,在请求线程中会通过RequestContext来共享状态,它内部是用ThreadLocal实现的,例如HttpServletRequest、HttpServletResponse、异常信息等。部分源码如下:

    public class RequestContext extends ConcurrentHashMap<String, Object> {
    
        private static final Logger LOG = LoggerFactory.getLogger(RequestContext.class);
    
        protected static Class<? extends RequestContext> contextClass = RequestContext.class;
    
        private static RequestContext testContext = null;
    
        protected static final ThreadLocal<? extends RequestContext> threadLocal = new ThreadLocal<RequestContext>() {
            @Override
            protected RequestContext initialValue() {
                try {
                    return contextClass.newInstance();
                } catch (Throwable e) {
                    throw new RuntimeException(e);
                }
            }
        };

      //.......
    }

    zuul中不同类型的filter执行逻辑的核心在ZuulServlet类中,主要代码如下:

    public class ZuulServlet extends HttpServlet {
    
        private static final long serialVersionUID = -3374242278843351500L;
        private ZuulRunner zuulRunner;
    
    
        @Override
        public void init(ServletConfig config) throws ServletException {
            super.init(config);
    
            String bufferReqsStr = config.getInitParameter("buffer-requests");
            boolean bufferReqs = bufferReqsStr != null && bufferReqsStr.equals("true") ? true : false;
    
            zuulRunner = new ZuulRunner(bufferReqs);
        }
    
        @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
                RequestContext context = RequestContext.getCurrentContext();
                context.setZuulEngineRan();
    
                try {
                    preRoute(); //如果preRoute方法在执行的时候出现异常,直接就抛出500异常,不会走catch中的error方法,见下图FilterProcessor类中的preRoute方法。
                } catch (ZuulException e) {
                    error(e); //如果preRoute在执行过程中,抛出Zuul异常,这里被捕捉到以后,会执行error方法,打印堆栈信息,见下图FilterProcessor类中的error方法。
                    postRoute();
                    return;
                }
                try {
                    route();
                } catch (ZuulException e) {
                    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 {
                RequestContext.getCurrentContext().unset();
            }
        }

      //....... }

    zuul一共有4种不同的生命周期:

    1. pre:在zuul网关按照规则路由到下级服务之前执行,如果需要对请求进行预处理,可以使用这种类型的过滤器。如:认证鉴权,限流等。
    2. route:这种过滤器是zuul路由动作的执行者,是Apache HttpClient或Ribbon构建和发送原始HTTP请求的地方,现在也支持OKHTTP。
    3. post:这种过滤器是在端点请求完毕,返回结果或者发生异常后执行的filter。如果需要对返回的结果进行再次处理,可以在这种过滤中处理逻辑。
    4. error: 这种过滤器是在整个生命周期内,如果发生异常,就执行该filter,可以做全局异常处理。
  • 相关阅读:
    iOS开发中TableView的嵌套使用
    iOS弹出View同时使背影变暗
    APNs消息推送完整讲解
    oc学习之路----APNS消息推送从证书到代码(2015年4月26号亲试可用)
    oc学习之路----application.keyWindow.rootViewController与self.window.rootViewController与[self.window makeKeyAndVisible];小发现
    oc学习之路----application.keyWindow.rootViewController与self.window.rootViewController与[self.window makeKeyAndVisible];小发现
    数据库设计原则
    oc学习之路----QQ聊天界面
    oc学习之路----代理模式2-使用步骤
    oc学习之路----通过代码自定义cell
  • 原文地址:https://www.cnblogs.com/idoljames/p/11741382.html
Copyright © 2011-2022 走看看