Zuul【工作原理】

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

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

相关文档
最新文档