近日工作中用到了SpringCloud的Zuul网关。 希望在提供网关路由转发时,又方便额外提供一些Rest接口。
在摸索中,有如下几点理解:
1:查询Zuul的源码,其提供一个Servlet叫:ZuulServlet,其默认处理的路径为:/zuul。其源码如下。通过此可以获知,如果一个http请求使用该
Servlet,那么该http请求只能是路过转发(使用 zuul.routes 配置的地址就由ZuulServlet处理)。
@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();
} catch (ZuulException e) {
error(e);
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();
}
}
2:Zuul提供两个注解:@EnableZuulServer 和 @EnableZuulProxy。@EnableZuulProxy是@EnableZuulServer的增强版。其分配使用使用 ZuulServerAutoConfiguration 和ZuulProxyAutoConfiguration 分别自动注入对应的组件。 除了SpringCloud的官网介绍的差别外,还有如下差别:
2.1:@EnableZuulServer 转发的关键字是:forward.to, 可以在自定义ZuulFilter中,修改上下文RequestContext中此关键字对应的值来改变路由路径。
2.2:@EnableZuulServer 是使用 RequestDispatcher 类进行转发,那么其无法访问SpringCloud的SerivceID 和 自动进行负载均衡。
2.3:@EnableZuulProxy 默认使用的是RestClient进行路由,可以访问SpringCloud的SerivceID 和 自动进行负载均衡。其路由关键字是: serviceId
3:关于 ZuulFilter。
3.1:自定义ZuulFilter的 filterOrder 函数返回值很重要,其决定了在同类型的Filter中,执行的顺序,值越小的越先执行。
3.2:函数 shouldFilter() 为false的Filter则不会被执行。
3.3: run() 方法的返回值没什么用处。 此方法类如果抛出异常,则同类型的其余为执行的Filter则不会再执行