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);
    				}
    			}
    		}
    
    	}
    
    }
    
  • 相关阅读:
    [转]看懂UML类图
    [转]客户需要什么样的业务解决方案
    [转]逻辑和计算机
    [转]数据库备份与恢复方案
    125个工具与技术(PMBOK2008)
    72个可交付成果(PMBOK2008)
    47个过程(PMBOK2008)
    项目管理详细任务(PMBOK2008)
    项目管理过程组和知识领域表(PMBOK2008)
    项 目 管 理 知 识 体 系 指 南 (PMBOK2008)
  • 原文地址:https://www.cnblogs.com/killbug/p/9974566.html
Copyright © 2011-2022 走看看