先开个头吧

作为偶尔点进源码的时候看到东西,或是学到,或是不解,或是惊讶,之后的一些记录。从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. 老版本db2这里下

    https://www-01.ibm.com/support/docview.wss?uid=swg27007053 db2 10.5.10.1.9.x等 下最新FIX版即可

  2. Problem - 1062 http://acm.hdu.edu.cn/showproblem.php?pid=1062

    对输入字符串的字符的倒置,在这个程序中,我觉得自己最大的问题是怎么识别一个字符,代码中有t个字符串,每个字符串,每个字符串中有若干个单词,单词之间有空格,所以对于下列的正确答案,我的疑惑是当我键盘输入 ...

  3. Android 音视频深入 十八 FFmpeg播放视频,有声音(附源码下载)

    项目地址https://github.com/979451341/AudioVideoStudyCodeTwo/tree/master/FFmpegv%E6%92%AD%E6%94%BE%E8%A7% ...

  4. HTML、CSS(小笔记)

    这是我自己在学习html.css时觉得要记的东西太多总结一些较为常用的标签. HTML <p></p>段落标签 <hn></hn>标题标签n数值为1~6 ...

  5. angular-cli.json常见配置

    { "project": { "name": "ng-admin", //项目名称 "ejected": false / ...

  6. 常用命令和sql

    常用命令: mvn idea:idea //生成.ipr项目文件 mvn clean install -Dmaven.test.skip=true mvn install:install-file - ...

  7. FPGA设计中的复位

    (1)异步复位与同步复位的写法 1.异步复位与同步复位的区别? 同步复位:若复位信号在时钟有效边沿到来时刻为有效,则执行一次复位操作. 优点: 1)同步复位是离散的,所以非常有利于仿真器的仿真: 2) ...

  8. docker学习常用指令---第五章节

    前面我们了解了docker的基本概念,和docker镜像,端口相关的内容.在具体的实际操作过程中,我们需要了解一些相关的docker操作指令. 一.Docker save指令 指令功能:将指定镜像保存 ...

  9. selenium中的对文本进行全选,复制,粘贴,剪切和删除的操作

    # 键盘全选操作from selenium.webdriver.common.keys import Keysdriver.find_element_by_css_selector('#key-dem ...

  10. linux下ftp权限控制

    需求背景: 1.创建2个账号给联调的系统使用读取我方服务器提供的文件信息.只允许看到限定的目录,对目录下的文件只有只读权限,禁止shell登录. 2.创建一个内部账号提供文件信息,只允许看到限定的目录 ...