Zuul 架构图
Zuul的官方文档中的架构图
从架构图中可以看到 Zuul
通过Zuul Servlet
和 一系列 Zuul Filter
来完成智能路由和过滤器的功能。
Zuul 工作原理概述(转)
在Zuul
中,整个请求的过程是这样的,首先将请求给 ZuulServlet
处理,ZuulServlet
中有一个ZuulRunner
对象,该对象中初始化了RequestContext
, RequestContext
作为整个请求的上下文,封装了请求的一些数据,并被所有的ZuulFilter
共享。ZuulRunner
中还有 FilterProcessor
,FilterProcessor
作为执行所有的ZuulFilter
的管理器。FilterProcessor
从 FilterLoader
中获取ZuulFilter
,而ZuulFilter
是被FilterFileManager
所加载,并支持groovy
热加载,采用了轮询的方式热加载。
有了这些Filter
之后,ZuulServlet
首先执行的pre
类型的过滤器,再执行route
类型的过滤器,最后执行的是post
类型的过滤器。
如果在执行这些过滤器有错误的时候则会执行error
类型的过滤器。执行完这些过滤器,最终将请求的结果返回给客户端。
Zuul 启动—源码分析
在程序的启动类上加@EnableZuulProxy
注解,我们可以使用Zuul
提供的功能了,该注解的源码为:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Import({ZuulProxyMarkerConfiguration.class})
public @interface EnableZuulProxy {
}
源码中,@EnableZuulProxy
引入了ZuulProxyMarkerConfiguration
配置类,跟踪ZuulProxyMarkerConfiguration
类:
public class ZuulProxyMarkerConfiguration {
public ZuulProxyMarkerConfiguration() {
}
@Bean
public ZuulProxyMarkerConfiguration.Marker zuulProxyMarkerBean() {
return new ZuulProxyMarkerConfiguration.Marker();
}
class Marker {
Marker() {
}
}
}
在ZuulProxyMarkerConfiguration
配置类中,发现只是注册了一个ZuulProxyMarkerConfiguration.Marker
的bean
。我们通过分析应该会有依赖这个bean
的配置类。然后我们找到了 ZuulProxyAutoConfiguration
依赖了ZuulProxyMarkerConfiguration.Marker
的bean
。
跟踪 ZuulProxyAutoConfiguration
:
@Configuration
@Import({RestClientRibbonConfiguration.class, OkHttpRibbonConfiguration.class, HttpClientRibbonConfiguration.class, HttpClientConfiguration.class})
@ConditionalOnBean({Marker.class})
public class ZuulProxyAutoConfiguration extends ZuulServerAutoConfiguration {
@Bean
@ConditionalOnMissingBean({DiscoveryClientRouteLocator.class})
public DiscoveryClientRouteLocator discoveryRouteLocator() {
return new DiscoveryClientRouteLocator(this.server.getServlet().getContextPath(), this.discovery, this.zuulProperties, this.serviceRouteMapper, this.registration);
}
@Bean
@ConditionalOnMissingBean({PreDecorationFilter.class})
public PreDecorationFilter preDecorationFilter(RouteLocator routeLocator, ProxyRequestHelper proxyRequestHelper) {
return new PreDecorationFilter(routeLocator, this.server.getServlet().getContextPath(), this.zuulProperties, proxyRequestHelper);
}
@Bean
@ConditionalOnMissingBean({RibbonRoutingFilter.class})
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
@ConditionalOnMissingBean({ServiceRouteMapper.class})
public ServiceRouteMapper serviceRouteMapper() {
return new SimpleServiceRouteMapper();
}
}
我们发现在类ZuulProxyAutoConfiguration
中,引入了RestClientRibbonConfiguration
, OkHttpRibbonConfiguration
, HttpClientRibbonConfiguration
, HttpClientConfiguration
,Zuul
默认是用HttpClientRibbonConfiguration
做负载均衡配置, 注入了DiscoveryClient
、RibbonConfiguration
用作负载均衡相关。注入了一些列的Filter
,pre
类型: PreDecorationFilter
; // 装饰 Requestroute
类型: RibbonRoutingFilter
, SimpleHostRoutingFilter
; // 路由Filter
在ZuulProxyAutoConfiguration
的父类ZuulServerAutoConfiguration
中,也引入了一些配置信息:
@EnableConfigurationProperties({ZuulProperties.class})
@ConditionalOnClass({ZuulServlet.class, ZuulServletFilter.class})
@ConditionalOnBean({Marker.class})
public class ZuulServerAutoConfiguration {
// 在缺失`ZuulServlet`的情况下注入`ZuulServlet`
@Bean
@ConditionalOnMissingBean(
name = {"zuulServlet"}
)
@ConditionalOnProperty(
name = {"zuul.use-filter"},
havingValue = "false",
matchIfMissing = true
)
public ServletRegistrationBean zuulServlet() {
ServletRegistrationBean<ZuulServlet> servlet = new ServletRegistrationBean(new ZuulServlet(), new String[]{this.zuulProperties.getServletPattern()});
servlet.addInitParameter("buffer-requests", "false");
return servlet;
}
// 在缺失`ZuulServletFilter`的情况下注入`ZuulServletFilter`
@Bean
@ConditionalOnMissingBean(
name = {"zuulServletFilter"}
)
@ConditionalOnProperty(
name = {"zuul.use-filter"},
havingValue = "true",
matchIfMissing = false
)
public FilterRegistrationBean zuulServletFilter() {
FilterRegistrationBean<ZuulServletFilter> filterRegistration = new FilterRegistrationBean();
filterRegistration.setUrlPatterns(Collections.singleton(this.zuulProperties.getServletPattern()));
filterRegistration.setFilter(new ZuulServletFilter());
filterRegistration.setOrder(2147483647);
filterRegistration.addInitParameter("buffer-requests", "false");
return filterRegistration;
}
// 注入 `ServletDetectionFilter`
@Bean
public ServletDetectionFilter servletDetectionFilter() {
return new ServletDetectionFilter();
}
// 注入 `FormBodyWrapperFilter`
@Bean
public FormBodyWrapperFilter formBodyWrapperFilter() {
return new FormBodyWrapperFilter();
}
// 注入 `DebugFilter`
@Bean
public DebugFilter debugFilter() {
return new DebugFilter();
}
// 注入 `Servlet30WrapperFilter`
@Bean
public Servlet30WrapperFilter servlet30WrapperFilter() {
return new Servlet30WrapperFilter();
}
// 注入 `SendResponseFilter`
@Bean
public SendResponseFilter sendResponseFilter(ZuulProperties properties) {
return new SendResponseFilter(this.zuulProperties);
}
// 注入 `SendErrorFilter`
@Bean
public SendErrorFilter sendErrorFilter() {
return new SendErrorFilter();
}
// 注入 `SendForwardFilter`
@Bean
public SendForwardFilter sendForwardFilter() {
return new SendForwardFilter();
}
@Configuration
protected static class ZuulFilterConfiguration {
@Autowired
private Map<String, ZuulFilter> filters;
protected ZuulFilterConfiguration() {
}
// ZuulFilterInitializer,在初始化类中将Filter向FilterRegistry注册
@Bean
public ZuulFilterInitializer zuulFilterInitializer(CounterFactory counterFactory, TracerFactory tracerFactory) {
FilterLoader filterLoader = FilterLoader.getInstance();
FilterRegistry filterRegistry = FilterRegistry.instance();
return new ZuulFilterInitializer(this.filters, counterFactory, tracerFactory, filterLoader, filterRegistry);
}
}
}
父类ZuulServerAutoConfiguration
中,在缺失ZuulServlet
,ZuulServletFilter
的bean
的情况下,注入ZuulServlet
,ZuulServletFilter
。同时也注入了其他的过滤器,pre
类型: ServletDetectionFilter
,DebugFilter
,Servlet30WrapperFilter
;post
类型: SendResponseFilter
; // 响应处理Filterroute
类型: SendForwardFilter
; // 重定向处理Filtererror
类型 : SendErrorFilter
; // 错误处理Filter
初始化ZuulFilterInitializer
类,通过FilterLoader
将所有的Filter
向FilterRegistry
注册。我们看一下ZuulFilterInitializer
类中部分代码
public class ZuulFilterInitializer {
// 初始化完成后注册所有的Filter
@PostConstruct
public void contextInitialized() {
log.info("Starting filter initializer");
TracerFactory.initialize(this.tracerFactory);
CounterFactory.initialize(this.counterFactory);
Iterator var1 = this.filters.entrySet().iterator();
while(var1.hasNext()) {
Entry<String, ZuulFilter> entry = (Entry)var1.next();
this.filterRegistry.put((String)entry.getKey(), (ZuulFilter)entry.getValue());
}
}
// 销毁前移除所有注册所有的Filter
@PreDestroy
public void contextDestroyed() {
log.info("Stopping filter initializer");
Iterator var1 = this.filters.entrySet().iterator();
while(var1.hasNext()) {
Entry<String, ZuulFilter> entry = (Entry)var1.next();
this.filterRegistry.remove((String)entry.getKey());
}
this.clearLoaderCache();
TracerFactory.initialize((TracerFactory)null);
CounterFactory.initialize((CounterFactory)null);
}
}