ZUUL
ZUUL功能如下:
认证
动态路由
安全
静态response处理
压力测试
流控
核心概念
type: 用于定义routing过程的各个阶段。
执行优先级:同一类型的Filter下filter的执行顺序。
critria: filter被执行满足的条件。
action: criteria满足后待执行的action。
ZuulFilter和IZuulFilter的核心接口:
//filter执行的满足条件
shoudFilter()
//filter的执行逻辑
run()
//filter类别
filterType()
//同类别filter的执行优先级
filterOrder()
看request的生命过程,http request在进入原始前先执行pre类型额filter。routing filter路由请求到后台的服务并处理服务返回的结果。post类型的filter则是执行事后分析。整个过程如下图所示:
重要的类
- ZuulServlet
实现了Servlet,将Zuul嵌入到Spring的Dispatch机制中。让spring mvc控制routing。 - SimpleRouteLocator
加载路由配置 - RequestContext
用于多个Filter之间共享信息,各个请求的数据存在ThreadLocal。 - ZuulProxyConfiguration
注入各类Filter - SimpleHostRoutingFilter
路由请求到后台处理
源码分析
看demo代码,首先找到入口
@SpringBootApplication
@EnableEurekaClient
@EnableZuulProxy
public class SpringZuulApplication {
public static void main(String[] args) {
SpringApplication.run(SpringZuulApplication.class, args);
}
}
- EnableZuulProxy类是关键,这个是走查源码的入口
@EnableCircuitBreaker
@EnableDiscoveryClient
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(ZuulProxyConfiguration.class)
public @interface EnableZuulProxy {
}
顺着该类看到了ZuulProxyAutoConfiguration,类中注入了DiscoveryClient,ServiceRouteMapper,Registration
@SuppressWarnings("rawtypes")
@Autowired(required = false)
private List requestCustomizers = Collections.emptyList();
@Autowired(required = false)
private Registration registration;
@Autowired
private DiscoveryClient discovery;
@Autowired
private ServiceRouteMapper serviceRouteMapper;
还注入了PreDecorationFilter,RibbonRoutingFilter,SimpleHostRoutingFilter等。也就是注入了一些内置额pre,route,post类型的filter。
从源码不难发现,ZuulProxyAutoConfiguration集成了ZuulServerAutoConfiguration类
public class ZuulProxyAutoConfiguration extends ZuulServerAutoConfiguration {
@SuppressWarnings("rawtypes")
@Autowired(required = false)
private List requestCustomizers = Collections.emptyList();
@Autowired(required = false)
private Registration registration;
@Autowired
private DiscoveryClient discovery;
@Autowired
private ServiceRouteMapper serviceRouteMapper;
}
我们看下ZuulServerAutoConfiguration类做了什么事情。
打开ZuulServerAutoConfiguration的实现,发现注入了一些bean,比如SimpleRouteLocator,ZuulController,ZuulHandlerMapping,ZuulRefreshListener,还有ServletDetectionFilter,SendResponseFilter,SendErrorFilter等通用过滤器。
// pre filters
@Bean
public PreDecorationFilter preDecorationFilter(RouteLocator routeLocator,
ProxyRequestHelper proxyRequestHelper) {
return new PreDecorationFilter(routeLocator, this.server.getServletPrefix(),
this.zuulProperties, proxyRequestHelper);
}
// route filters
@Bean
public RibbonRoutingFilter ribbonRoutingFilter(ProxyRequestHelper helper,
RibbonCommandFactory> ribbonCommandFactory) {
RibbonRoutingFilter filter = new RibbonRoutingFilter(helper, ribbonCommandFactory,
this.requestCustomizers);
return filter;
}
@Bean
@ConditionalOnMissingBean({SimpleHostRoutingFilter.class, CloseableHttpClient.class})
public SimpleHostRoutingFilter simpleHostRoutingFilter(ProxyRequestHelper helper,
ZuulProperties zuulProperties,
ApacheHttpClientConnectionManagerFactory connectionManagerFactory,
ApacheHttpClientFactory httpClientFactory) {
return new SimpleHostRoutingFilter(helper, zuulProperties,
connectionManagerFactory, httpClientFactory);
}
@Bean
@ConditionalOnMissingBean({SimpleHostRoutingFilter.class})
public SimpleHostRoutingFilter simpleHostRoutingFilter2(ProxyRequestHelper helper,
ZuulProperties zuulProperties,
CloseableHttpClient httpClient) {
return new SimpleHostRoutingFilter(helper, zuulProperties,
httpClient);
}
@Bean
public ApplicationListener zuulDiscoveryRefreshRoutesListener() {
return new ZuulDiscoveryRefreshListener();
}
@Bean
@ConditionalOnMissingBean(ServiceRouteMapper.class)
public ServiceRouteMapper serviceRouteMapper() {
return new SimpleServiceRouteMapper();
}
@Configuration
@ConditionalOnMissingClass("org.springframework.boot.actuate.endpoint.Endpoint")
protected static class NoActuatorConfiguration {
@Bean
public ProxyRequestHelper proxyRequestHelper(ZuulProperties zuulProperties) {
ProxyRequestHelper helper = new ProxyRequestHelper();
helper.setIgnoredHeaders(zuulProperties.getIgnoredHeaders());
helper.setTraceRequestBody(zuulProperties.isTraceRequestBody());
return helper;
}
}
最为重要的是
@Configuration
protected static class ZuulFilterConfiguration
在该配置类中,注入了ZuulFilterInitializer对象,该对象中完成Filter的注册(查看@PostConstruct)。
自此Zuul完成了配置的初始化。
流程
说了一堆,一个请求进来,是如何经过Zuul处理的咧。这就需要用到ZuulServlet这个类了,该类实现了HttpServlet。重写的service方法中,使用了模板设计模式,依次调用了
preRoute()
route()
postRoute()
ZuulServlet中持有一个ZuulRunner对象,该对象调用了FilterProcessor的preRoute(),route()以及postRoute()。为了代码的复用,以上的方法均调用runFilters(String sType)方法
List list = FilterLoader.getInstance().getFiltersByType(sType);
for(int i=0; i
FilterLoader类中持有FilterRegistry对象获取之前注册上的所有Filter。自此整个过程分析完毕。