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,可以做全局异常处理。

Zuul【工作原理】的更多相关文章

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

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

  2. 菜鸟学Struts2——Struts工作原理

    在完成Struts2的HelloWorld后,对Struts2的工作原理进行学习.Struts2框架可以按照模块来划分为Servlet Filters,Struts核心模块,拦截器和用户实现部分,其中 ...

  3. 【夯实Nginx基础】Nginx工作原理和优化、漏洞

    本文地址 原文地址 本文提纲: 1.  Nginx的模块与工作原理    2.  Nginx的进程模型    3 . NginxFastCGI运行原理        3.1 什么是 FastCGI   ...

  4. HashMap的工作原理

    HashMap的工作原理   HashMap的工作原理是近年来常见的Java面试题.几乎每个Java程序员都知道HashMap,都知道哪里要用HashMap,知道HashTable和HashMap之间 ...

  5. 【Oracle 集群】ORACLE DATABASE 11G RAC 知识图文详细教程之RAC 工作原理和相关组件(三)

    RAC 工作原理和相关组件(三) 概述:写下本文档的初衷和动力,来源于上篇的<oracle基本操作手册>.oracle基本操作手册是作者研一假期对oracle基础知识学习的汇总.然后形成体 ...

  6. ThreadLocal 工作原理、部分源码分析

    1.大概去哪里看 ThreadLocal 其根本实现方法,是在Thread里面,有一个ThreadLocal.ThreadLocalMap属性 ThreadLocal.ThreadLocalMap t ...

  7. Servlet的生命周期及工作原理

    Servlet生命周期分为三个阶段: 1,初始化阶段  调用init()方法 2,响应客户请求阶段 调用service()方法 3,终止阶段 调用destroy()方法 Servlet初始化阶段: 在 ...

  8. 代码管理工具 --- git的学习笔记二《git的工作原理》

    通过几个问题来学习代码管理工具之git 一.git是什么?为什么要用它?使用它的好处?它与svn的区别,在Mac上,比较好用的git图形界面客户端有 git 是分布式的代码管理工具,使用它是因为,它便 ...

  9. 【原】Learning Spark (Python版) 学习笔记(三)----工作原理、调优与Spark SQL

    周末的任务是更新Learning Spark系列第三篇,以为自己写不完了,但为了改正拖延症,还是得完成给自己定的任务啊 = =.这三章主要讲Spark的运行过程(本地+集群),性能调优以及Spark ...

  10. 浏览器内部工作原理--作者:Tali Garsiel

    本篇内容为转载,主要用于个人学习使用,作者:Tali Garsiel 一.介绍 浏览器可以被认为是使用最广泛的软件,本文将介绍浏览器的工作原理,我们将看到,从你在地址栏输入google.com到你看到 ...

随机推荐

  1. Java SpringBoot 实体类数据自动验证

    package demo.dto; import org.hibernate.validator.constraints.Length; import javax.validation.constra ...

  2. Java 学习之路(2)程序基本要素

    编写一个程序,基本要素包括:标识符.关键字.注释.修饰符.块.语句.类和main()方法. 标识符 概念 在Java语言中:标识符是用来给类.对象.方法.变量.接口和自定义数据类型命名的. 标识符组成 ...

  3. const经典面试题

    1> const int age1 = 21; age1 = 100; // 编译报错 2> int const age2 = 22; 3> const int *age3 = 23 ...

  4. 小福bbs-冲刺日志(第三天)

    [小福bbs-冲刺日志(第三天)] 这个作业属于哪个课程 班级链接 这个作业要求在哪里 作业要求的链接 团队名称 小福bbs 这个作业的目标 前端交付部分页面给后端 ,后端开始完成部分功能 作业的正文 ...

  5. win7+64位+Java学习基本软件安装+环境配置+eclipse(IDE)

    一.下载安装JDK 1.安装包下载地址:http://www.oracle.com/technetwork/java/javase/downloads/jdk9-downloads-3848520.h ...

  6. PyCharm 中写 Turtle代码没提示以及标黄问题

    PyCharm 中在使用Turtle(海龟)库绘图体系时,代码明明是正确可以运行的,但是没有提示 ,代码出现黄色标记以及红色波浪线 ,经验不足的人还以为自己的书写方法错误,毕竟出现了红色波浪线,效果如 ...

  7. Qt类关系一览表

  8. Status Code: 431 Request Header Fields Too Large

    Status Code: 431 Request Header Fields Too Large    

  9. 获取并打印Spring容器中所有的Bean名称

    思路: 1.实现Spring的ApplicationContextAware接口,重写setApplicationContext方法,将得到的ApplicationContext对象保存到一个静态变量 ...

  10. 009-Spring Boot全局配置跨域请求支持

    1.Spring Boot 2.0以前全局配置跨域主要是继承WebMvcConfigurerAdapter @Configuration public class CorsConfig extends ...