先开个头吧

作为偶尔点进源码的时候看到东西,或是学到,或是不解,或是惊讶,之后的一些记录。从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);
}
}
} } }

zuul1.3源码扒一扒(1)的更多相关文章

  1. SpringBoot SpringApplication底层源码分析与自动装配

    目录 抛出问题 @SpringBootApplication注解剖析 SpringApplication类剖析 第一步:配置SpringBoot Bean来源 第二步 :自动推断SpringBoot的 ...

  2. 学会阅读源码后,我觉得自己better了

    我有一个大学同学,名叫石磊,我在之前的文章里提到过几次,我们俩合作过很多项目.只要有他在,我就特别放心,因为几乎所有难搞的问题,到他这,都能够巧妙地化解.他给我印象最深刻的一句话就是,"有啥 ...

  3. bilibili源码泄漏后,程序员们从代码里扒出来的彩蛋

    昨天bilibili又上热搜了,被某人在github上开了个账号,传了份整个后端代码到github,这是被人扒光了衣服看个精光啊. 这件事情,作为程序员的我们除了调侃和fork的同时,想一想,造成这个 ...

  4. 软件扒网站? 爬虫? F12查看源码? 查看网页源代码?浏览器sources? 区别和联系!

    1.软件扒网站: 利用各类扒站网站,如仿站小工具8.0,可以按照规则将网站的未经浏览器简析的前端代码扒下来,并整理成css,js,html等文件夹,很方便.(当然看不到ajax等相关代码) 备注:如果 ...

  5. jQuery源码学习扒一扒jQuery对象初使化

    神奇的jQuery可以这样玩jQuery("#id").css()或 jQuery("#id").html() 这么玩jQuery("#id" ...

  6. 如何扒取一个网站的HTML和CSS源码

    一个好的前端开发,当看到一个很炫的页面的时候会本着学习的心态,想知道网站的源码.以下内容只是为了大家更好的学习,拒绝抄袭,支持正版. 1 首先我们要有一个chrome浏览器 2 在本地创建相关文件夹 ...

  7. .net core 源码解析-web app是如何启动并接收处理请求

    最近.net core 1.1也发布了,蹒跚学步的小孩又长高了一些,园子里大家也都非常积极的在学习,闲来无事,扒拔源码,涨涨见识. 先来见识一下web站点是如何启动的,如何接受请求,.net core ...

  8. jQuery 2.0.3 源码分析Sizzle引擎 - 解析原理

    声明:本文为原创文章,如需转载,请注明来源并保留原文链接Aaron,谢谢! 先来回答博友的提问: 如何解析 div > p + div.aaron input[type="checkb ...

  9. Bootstrap Navbar应用及源码解析

    目的: 用Bootstrap Navbar component 实现一个响应式导航 理解Bootstrap Navbar component是如何工作的(不包括collepse.js) 清楚自己添加一 ...

随机推荐

  1. kafka producer batch 发送消息

    1. 使用 KafkaProducer 发送消息,是按 batch 发送的,producer 首先把消息放入 ProducerBatch 中: org.apache.kafka.clients.pro ...

  2. uiautomatorviewer工具的安装与使用

    Android自动化测试应用<一><uiautomatorviewer工具的安装与使用> OldKe 关注 2018.01.25 18:00* 字数 488 阅读 2083评论 ...

  3. 以数之名:In Praise of APL 后记

    原文:http://www.jsoftware.com/papers/perlis77.htm 标题:In Praise of APL: A Language for Lyrical Programm ...

  4. VS2013中调驱动

    https://msdn.microsoft.com/en-us/library/windows/hardware/jj200334(v=vs.85).aspx 需要注意的就是 debugport:n ...

  5. 8ci

  6. 软件151 王楚博 maven的导入

    一.maven 包的导入 清单如下: <!-- Inherit defaults from Spring Boot --> <parent> <groupId>or ...

  7. typescript 属性默认值使用箭头函数 this指向问题

    今天注意到前端小伙伴用react 定义component class的方法的时候是通过箭头函数的方式,表示好奇. class Test extends React.Component { public ...

  8. Linux 虚拟文件系统概述

    转自:http://blog.csdn.net/u011373710/article/details/70198080 文章梗概 本文首先以“尽量不涉及源代码”的方式讨论Linux虚拟文件系统的存在的 ...

  9. ecplise多个版本tomcat的使用

    在ecplise中修改配置文件,或者直接在server.xml中修改,将tomcat三个端口号修改为与另一个tomcat不同即可.

  10. 常用的数组函数-S

    header('content-type:text/html;charset=utf-8'); //声明一个数组 $arr=['one'=>'aaa','two'=>'bbb','thre ...