一,开启ZUUL支持标识
加入zuul一般如下
@EnableZuulProxy@SpringCloudApplicationpublic class Application { public static void main(String[] args) { new SpringApplicationBuilder(Application.class).web(true).run(args); } }
其中@EnableZuulProxy是开启zuul的功能支持。
跟踪进EnableZuulProxy,源码如下
@EnableCircuitBreaker@EnableDiscoveryClient@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Import(ZuulProxyMarkerConfiguration.class)public @interface EnableZuulProxy {}
除了引入discoveryClient注册eureka外,主要就做了一件事,引入了ZuulProxyMarkerConfiguration,@Import(ZuulProxyMarkerConfiguration.class), ZuulProxyMarkerConfiguration新建了个Marker的bean返回。
如下:
@Configurationpublic class ZuulProxyMarkerConfiguration { @Bean public Marker zuulProxyMarkerBean() { return new Marker(); } class Marker { }}
后面的zuul配置会根据是否有这个maker对象而使配置生效
@ConditionalOnBean(ZuulServerMarkerConfiguration.Marker.class)
二,zuul初始化配置
更多初始化具体的配置,zuul是用的SPI方式进行
SPI入口
用SPI管理所有注册,spring.factories如下:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration,\org.springframework.cloud.netflix.feign.ribbon.FeignRibbonClientAutoConfiguration,\org.springframework.cloud.netflix.feign.FeignAutoConfiguration,\org.springframework.cloud.netflix.feign.encoding.FeignAcceptGzipEncodingAutoConfiguration,\org.springframework.cloud.netflix.feign.encoding.FeignContentGzipEncodingAutoConfiguration,\org.springframework.cloud.netflix.hystrix.HystrixAutoConfiguration,\org.springframework.cloud.netflix.hystrix.security.HystrixSecurityAutoConfiguration,\org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration,\org.springframework.cloud.netflix.rx.RxJavaAutoConfiguration,\org.springframework.cloud.netflix.metrics.servo.ServoMetricsAutoConfiguration,\org.springframework.cloud.netflix.zuul.ZuulServerAutoConfiguration,\org.springframework.cloud.netflix.zuul.ZuulProxyAutoConfigurationorg.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker=\org.springframework.cloud.netflix.hystrix.HystrixCircuitBreakerConfigurationorg.springframework.boot.env.EnvironmentPostProcessor=\org.springframework.cloud.netflix.metrics.ServoEnvironmentPostProcessor
其中和zuul相关初始化的主要是
org.springframework.cloud.netflix.zuul.ZuulServerAutoConfiguration
和
org.springframework.cloud.netflix.zuul.ZuulProxyAutoConfiguration
1. ZuulServerAutoConfiguration
@Configuration@EnableConfigurationProperties({ ZuulProperties.class })@ConditionalOnClass(ZuulServlet.class)@ConditionalOnBean(ZuulServerMarkerConfiguration.Marker.class) //这里用到上面的@EnableZuulProxy的引入做判断// Make sure to get the ServerProperties from the same place as a normal web app would@Import(ServerPropertiesAutoConfiguration.class)public class ZuulServerAutoConfiguration {@Autowiredprotected ZuulProperties zuulProperties; @Autowiredprotected ServerProperties server; @Autowired(required = false)private ErrorController errorController;... ...
属性相关
ZuulProperties zuulProperties; // yml里的配置,zuul开头相关配置在这注入
ServerProperties server; // yml里的配置,zuul开头相关配置在这注入
ErrorController errorController; //处理错误的controller,自定义实现
几个重要bean:
ZuulController 接管所有的请求,把所有请求交给zuulServlet去处理,所有请求会先到zuulcontroler再转到zuulServlet
ZuulRefreshListener 通过监听spring Context发布机制事件,监听心跳消息
几个重要Filter:
按ORDER的从小到大排列
ServletDetectionFilter -- PRE -3. 判断是否是走spring MVC还是直接走zuulservlet的, 并赋值 IS_DISPATCHER_SERVLET_REQUEST_KEY
Servlet30RequestWrapper -PRE -2. 把RequestServlet转换Servlet30RequestWrapper
FormBodyWrapperFilter -PRE -1. 封装成FormBodyRequestWrapper
DebugFilter -PRE 1. 用于动态开启debug日志,zuul.debug.request=true 开启debug模式
还几个核心flter注册在 org.springframework.cloud.netflix.zuul.ZuulProxyAutoConfiguration
PreDecorationFilter PRE 5, PreDecorationFilter 添加头,serviceId信息处理等
2, ZuulProxyAutoConfiguration
@Configuration@Import({ RibbonCommandFactoryConfiguration.RestClientRibbonConfiguration.class, RibbonCommandFactoryConfiguration.OkHttpRibbonConfiguration.class, RibbonCommandFactoryConfiguration.HttpClientRibbonConfiguration.class })@ConditionalOnBean(ZuulProxyMarkerConfiguration.Marker.class)public class ZuulProxyAutoConfiguration extends ZuulServerAutoConfiguration { @SuppressWarnings("rawtypes") @Autowired(required = false) private ListrequestCustomizers = Collections.emptyList(); @Autowired private DiscoveryClient discovery; @Autowired private ServiceRouteMapper serviceRouteMapper;
导入Ribbon相关的类
属性相关
DiscoveryClient discovery; // eureka客户端, eureka相关操作,如:根据serviceId获取实例所有机器列表
重要的Filter
PreDecorationFilter // 处理请求头,serviceId等信息的地方
RibbonRoutingFilter. //真正做转发的Filter,封装了nitfilx 全家桶的地方
SimpleHostRoutingFilter // 转发不走eureka的请求