概述
如何使用Spring Cloud Zuul?
之前的文章中,我们学习了Spring Cloud Zuul如何使用,这里再回顾下:
1.引入依赖,在启动类中添加@EnableZuulProxy,声明这是一个Zuul代理。
2.注册到Eureka Server,启动服务,访问这个端口,url中带上要请求的服务名。
Spring Cloud Zuul源码分析
既然是添加了@EnableZuulProxy注解,那还是先进入这个注解找线索吧。
/**
* Sets up a Zuul server endpoint and installs some reverse proxy filters in it, so it can
* forward requests to backend servers. The backends can be registered manually through
* configuration or via DiscoveryClient.
*
* @see EnableZuulServer for how to get a Zuul server without any proxying
*
* @author Spencer Gibb
* @author Dave Syer
*/
@EnableCircuitBreaker
@EnableDiscoveryClient
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(ZuulProxyConfiguration.class)
public @interface EnableZuulProxy {
}
从注释中可以看到,这个注解会启动一个Zuul server,并且给这个Zuul server装配一些代理过滤器,下面还提到了一个@EnableZuulServer注解,这个注解可以开启一个Zuul server,但是不配置代理。@EnableZuulProxy可以看成是@EnableZuulServer的增强版。
@EnableZuulProxy注解上import了ZuulProxyConfiguration类,从名字上看,这个就是zuul代理的配置类,这个类中,定义了DiscoveryClient和其他一些负载均衡相关的类,还初始化了一些Filter。
ZuulProxyConfiguration类继承了ZuulConfiguration,这个配置类就是对zuul进行一些配置的,里面可以看到会初始化ZuulServlet和其他一些Zuul的bean以及Filter。
在ZuulConfiguration中,还有个ZuulFilterConfiguration内部类,这个内部类中会初始化ZuulFilterInitializer,存放所有的Filters。
Zuul定义了四种类型的过滤器:
1.Pre Filter
2.Route Filter
3.Post Filter
4.Error Filter
Pre过滤器是请求路由到具体的服务之前执行的,可以用来做安全验证,参数验证等操作。
Route过滤器是用来将请求路由到具体的服务上。
Post过滤器是请求已经被路由到微服务之后执行的。
如果Pre,Route和Post过滤器在执行过程中发生了异常,会由Error过滤器处理。
下面是这四种过滤器的执行顺序:
请求会先经过per filters,然后到routing filters,再去请求到具体的服务上,返回response之后,就经过post filters。如果发生异常,交给error filters。还可以自己自己定义filters。
自己定义filter,需要继承ZuulFilter抽象类,重写下面这四个方法:
public class MyFilter extends ZuulFilter {
@Override
public String filterType() {
return "pre";
}
@Override
public int filterOrder() {
return 0;
}
@Override
public boolean shouldFilter() {
return false;
}
@Override
public Object run() {
return null;
}
}
其中,filterType方法,返回这个filter的类型,比如是pre类型的过滤器。
filterOrder是定义这个过滤器的执行顺序,值越小,越先执行。
shouldFIlter返回该过滤器是否开启,返回false,表示不执行这个过滤器。
run就是具体过滤器中需要执行的方法。
接下来再看下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();
}
}
从ZuulServlet中,也可以看出这个执行的逻辑。Zuul的主要功能,就是在这些Filter中了。
最后
以上就是欢呼西装为你收集整理的Spring Cloud Zuul源码分析的全部内容,希望文章能够帮你解决Spring Cloud Zuul源码分析所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复