zoukankan      html  css  js  c++  java
  • zuul1.3源码扒一扒(1)

    先开个头吧

    作为偶尔点进源码的时候看到东西,或是学到,或是不解,或是惊讶,之后的一些记录。从springcloud各个组件开始吧,计划文段保持间断,只道出核心点,不过各个文段保持连续。

    zuul作为spring cloud 推荐网关,搭建起来很方便。

    Spring Cloud 1.4.4 core jar包里面的package基本描述了整个微服务架构的核心部分,其中zuul也囊括其中。

    在使用zuul时我们会使用EnableZuulProxy注解,配合使用spring cloud。

    @EnableCircuitBreaker
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Import(ZuulProxyMarkerConfiguration.class)
    public @interface EnableZuulProxy {
    }
    

    @EnableCircuitBreaker 默认使用断路器 参考文档:https://martinfowler.com/bliki/CircuitBreaker.html

    @Import(ZuulProxyMarkerConfiguration.class)就技巧了。

    @Configuration
    public class ZuulProxyMarkerConfiguration {
       @Bean
       public Marker zuulProxyMarkerBean() {
          return new Marker();
       }
    
       class Marker {
       }
    }
    

    啥都没干,就是配置了个zuulProxyMarkerBean。看字面意思就猜差不多了,这个东西可以用于标记,标记都是用来判断什么用的。
    用于ZuulProxyAutoConfiguration的ConditionalOnBean,也就是使用EnableZuulProxy注解连带的开启了ZuulProxyAutoConfiguration的配置。

    还有个注解 EnableZuulServer 一样有个ZuulServerMarkerConfiguration 一样的道理。
    事实上EnableZuulProxy是EnableZuulServer的增强版,为什么,因为ZuulProxyAutoConfiguration继承ZuulServerAutoConfiguration。

    那么zuul的配置文件里有什么呢?我觉得最重要的一个spring cloud网关要组合两个组件:一个是Ribbon,一个是hystrix,后者签名通过EnableCircuitBreaker搞进来了,后续在写。
    核心关注两个类:ZuulProxyAutoConfiguration 和 ZuulServerAutoConfiguration

    @Configuration
    @Import({ RibbonCommandFactoryConfiguration.RestClientRibbonConfiguration.class,
    		RibbonCommandFactoryConfiguration.OkHttpRibbonConfiguration.class,
    		RibbonCommandFactoryConfiguration.HttpClientRibbonConfiguration.class,
    		HttpClientConfiguration.class })
    @ConditionalOnBean(ZuulProxyMarkerConfiguration.Marker.class)
    public class ZuulProxyAutoConfiguration extends ZuulServerAutoConfiguration {
    
    	@SuppressWarnings("rawtypes")
    	@Autowired(required = false)
    	private List<RibbonRequestCustomizer> requestCustomizers = Collections.emptyList();
    
    	@Autowired(required = false)
    	private Registration registration;
    
    	@Autowired
    	private DiscoveryClient discovery;
    
    	@Autowired
    	private ServiceRouteMapper serviceRouteMapper;
    
    	@Override
    	public HasFeatures zuulFeature() {
    		return HasFeatures.namedFeature("Zuul (Discovery)",
    				ZuulProxyAutoConfiguration.class);
    	}
    
    	@Bean
    	@ConditionalOnMissingBean(DiscoveryClientRouteLocator.class)
    	public DiscoveryClientRouteLocator discoveryRouteLocator() {
    		return new DiscoveryClientRouteLocator(this.server.getServletPrefix(),
    				this.discovery, this.zuulProperties, this.serviceRouteMapper, this.registration);
    	}
    
    	// 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<ApplicationEvent> 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
    	@ConditionalOnClass(Endpoint.class)
    	protected static class EndpointConfiguration {
    
    		@Autowired(required = false)
    		private TraceRepository traces;
    
    		@ConditionalOnEnabledEndpoint("routes")
    		@Bean
    		public RoutesEndpoint routesEndpoint(RouteLocator routeLocator) {
    			return new RoutesEndpoint(routeLocator);
    		}
    
    		@ConditionalOnEnabledEndpoint("routes")
    		@Bean
    		public RoutesMvcEndpoint routesMvcEndpoint(RouteLocator routeLocator,
    				RoutesEndpoint endpoint) {
    			return new RoutesMvcEndpoint(endpoint, routeLocator);
    		}
    
    		@ConditionalOnEnabledEndpoint("filters")
    		@Bean
    		public FiltersEndpoint filtersEndpoint() {
    			FilterRegistry filterRegistry = FilterRegistry.instance();
    			return new FiltersEndpoint(filterRegistry);
    		}
    
    		@Bean
    		public ProxyRequestHelper proxyRequestHelper(ZuulProperties zuulProperties) {
    			TraceProxyRequestHelper helper = new TraceProxyRequestHelper();
    			if (this.traces != null) {
    				helper.setTraces(this.traces);
    			}
    			helper.setIgnoredHeaders(zuulProperties.getIgnoredHeaders());
    			helper.setTraceRequestBody(zuulProperties.isTraceRequestBody());
    			return helper;
    		}
    	}
    
    	private static class ZuulDiscoveryRefreshListener
    			implements ApplicationListener<ApplicationEvent> {
    
    		private HeartbeatMonitor monitor = new HeartbeatMonitor();
    
    		@Autowired
    		private ZuulHandlerMapping zuulHandlerMapping;
    
    		@Override
    		public void onApplicationEvent(ApplicationEvent event) {
    			if (event instanceof InstanceRegisteredEvent) {
    				reset();
    			}
    			else if (event instanceof ParentHeartbeatEvent) {
    				ParentHeartbeatEvent e = (ParentHeartbeatEvent) event;
    				resetIfNeeded(e.getValue());
    			}
    			else if (event instanceof HeartbeatEvent) {
    				HeartbeatEvent e = (HeartbeatEvent) event;
    				resetIfNeeded(e.getValue());
    			}
    
    		}
    
    		private void resetIfNeeded(Object value) {
    			if (this.monitor.update(value)) {
    				reset();
    			}
    		}
    
    		private void reset() {
    			this.zuulHandlerMapping.setDirty(true);
    		}
    
    	}
    
    }
    
    @Configuration
    @EnableConfigurationProperties({ ZuulProperties.class })
    @ConditionalOnClass(ZuulServlet.class)
    @ConditionalOnBean(ZuulServerMarkerConfiguration.Marker.class)
    // Make sure to get the ServerProperties from the same place as a normal web app would
    @Import(ServerPropertiesAutoConfiguration.class)
    public class ZuulServerAutoConfiguration {
    
    	@Autowired
    	protected ZuulProperties zuulProperties;
    
    	@Autowired
    	protected ServerProperties server;
    
    	@Autowired(required = false)
    	private ErrorController errorController;
    
    	@Bean
    	public HasFeatures zuulFeature() {
    		return HasFeatures.namedFeature("Zuul (Simple)", ZuulServerAutoConfiguration.class);
    	}
    
    	@Bean
    	@Primary
    	public CompositeRouteLocator primaryRouteLocator(
    			Collection<RouteLocator> routeLocators) {
    		return new CompositeRouteLocator(routeLocators);
    	}
    
    	@Bean
    	@ConditionalOnMissingBean(SimpleRouteLocator.class)
    	public SimpleRouteLocator simpleRouteLocator() {
    		return new SimpleRouteLocator(this.server.getServletPrefix(),
    				this.zuulProperties);
    	}
    
    	@Bean
    	public ZuulController zuulController() {
    		return new ZuulController();
    	}
    
    	@Bean
    	public ZuulHandlerMapping zuulHandlerMapping(RouteLocator routes) {
    		ZuulHandlerMapping mapping = new ZuulHandlerMapping(routes, zuulController());
    		mapping.setErrorController(this.errorController);
    		return mapping;
    	}
    
    	@Bean
    	public ApplicationListener<ApplicationEvent> zuulRefreshRoutesListener() {
    		return new ZuulRefreshListener();
    	}
    
    	@Bean
    	@ConditionalOnMissingBean(name = "zuulServlet")
    	public ServletRegistrationBean zuulServlet() {
    		ServletRegistrationBean servlet = new ServletRegistrationBean(new ZuulServlet(),
    				this.zuulProperties.getServletPattern());
    		// The whole point of exposing this servlet is to provide a route that doesn't
    		// buffer requests.
    		servlet.addInitParameter("buffer-requests", "false");
    		return servlet;
    	}
    
    	// pre filters
    
    	@Bean
    	public ServletDetectionFilter servletDetectionFilter() {
    		return new ServletDetectionFilter();
    	}
    
    	@Bean
    	public FormBodyWrapperFilter formBodyWrapperFilter() {
    		return new FormBodyWrapperFilter();
    	}
    
    	@Bean
    	public DebugFilter debugFilter() {
    		return new DebugFilter();
    	}
    
    	@Bean
    	public Servlet30WrapperFilter servlet30WrapperFilter() {
    		return new Servlet30WrapperFilter();
    	}
    
    	// post filters
    
    	@Bean
    	public SendResponseFilter sendResponseFilter() {
    		return new SendResponseFilter();
    	}
    
    	@Bean
    	public SendErrorFilter sendErrorFilter() {
    		return new SendErrorFilter();
    	}
    
    	@Bean
    	public SendForwardFilter sendForwardFilter() {
    		return new SendForwardFilter();
    	}
    
    	@Bean
    	@ConditionalOnProperty(value = "zuul.ribbon.eager-load.enabled", matchIfMissing = false)
    	public ZuulRouteApplicationContextInitializer zuulRoutesApplicationContextInitiazer(
    			SpringClientFactory springClientFactory) {
    		return new ZuulRouteApplicationContextInitializer(springClientFactory,
    				zuulProperties);
    	}
    
    	@Configuration
    	protected static class ZuulFilterConfiguration {
    
    		@Autowired
    		private Map<String, ZuulFilter> filters;
    
    		@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);
    		}
    
    	}
    
    	@Configuration
    	@ConditionalOnClass(CounterService.class)
    	protected static class ZuulCounterFactoryConfiguration {
    
    		@Bean
    		@ConditionalOnBean(CounterService.class)
    		public CounterFactory counterFactory(CounterService counterService) {
    			return new DefaultCounterFactory(counterService);
    		}
    	}
    
    	@Configuration
    	protected static class ZuulMetricsConfiguration {
    
    		@Bean
    		@ConditionalOnMissingBean(CounterFactory.class)
    		public CounterFactory counterFactory() {
    			return new EmptyCounterFactory();
    		}
    
    		@ConditionalOnMissingBean(TracerFactory.class)
    		@Bean
    		public TracerFactory tracerFactory() {
    			return new EmptyTracerFactory();
    		}
    
    	}
    
    	private static class ZuulRefreshListener
    			implements ApplicationListener<ApplicationEvent> {
    
    		@Autowired
    		private ZuulHandlerMapping zuulHandlerMapping;
    
    		private HeartbeatMonitor heartbeatMonitor = new HeartbeatMonitor();
    
    		@Override
    		public void onApplicationEvent(ApplicationEvent event) {
    			if (event instanceof ContextRefreshedEvent
    					|| event instanceof RefreshScopeRefreshedEvent
    					|| event instanceof RoutesRefreshedEvent) {
    				this.zuulHandlerMapping.setDirty(true);
    			}
    			else if (event instanceof HeartbeatEvent) {
    				if (this.heartbeatMonitor.update(((HeartbeatEvent) event).getValue())) {
    					this.zuulHandlerMapping.setDirty(true);
    				}
    			}
    		}
    
    	}
    
    }
    
  • 相关阅读:
    Python入门11 —— 基本数据类型的操作
    Win10安装7 —— 系统的优化
    Win10安装6 —— 系统的激活
    Win10安装5 —— 系统安装步骤
    Win10安装4 —— 通过BIOS进入PE
    Win10安装2 —— 版本的选择与下载
    Win10安装1 —— 引言与目录
    Win10安装3 —— U盘启动工具安装
    虚拟机 —— VMware Workstation15安装教程
    Python入门10 —— for循环
  • 原文地址:https://www.cnblogs.com/killbug/p/9974566.html
Copyright © 2011-2022 走看看