spring cloud源码分析-zuul路由的部分源码解析-阿里云开发者社区

开发者社区> dfuwei> 正文

spring cloud源码分析-zuul路由的部分源码解析

简介: 主要介绍spring cloud zuul组件中的路由定位器的部分源码
+关注继续查看

版本:
spring-boot:1.5.3.RELEASE;
spring cloud:Dalston.RELEASE(1.3.0.RELEASE)

路由定位器

  • 配置所在jar包:spring-cloud-netflix-core-1.3.0.RELEASE.jar
  • 顶层接口:RouteLocator
  • 可刷新的路由:RefreshableRouteLocator extends RouteLocator
  • 路由处理器:CompositeRouteLocator implements RefreshableRouteLocator,所有的路由定位器都交由给它处理
  • 默认加载的路由定位器:SimpleRouteLocator implements RouteLocator, Ordered,实现Ordered接口达到排序的效果
  • 配置类:ZuulProxyConfiguration extends ZuulConfiguration,ZuulConfiguration中包含默认的一些公共的filter,ZuulProxyConfiguration包含spring cloud的需要的一些filter,如:host解析、ribbon负载均衡等
  • zuul初始化配置不是通过spring.factories配置文件,而是通过@EnableZuulProxy注解引入配置的,源码如下:
@EnableCircuitBreaker
@EnableDiscoveryClient
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(ZuulProxyConfiguration.class)
public @interface EnableZuulProxy {
}
  • zuul路由的请求是通过filter发出去的
  • 可刷新的路由定位器(RefreshableRouteLocator)是基于监听spring容器事件实现的,并且都是在配置类中(内部静态类),有两个地方:

    ZuulConfiguration中的监听:

//加载bean
@Bean
public ApplicationListener<ApplicationEvent> zuulRefreshRoutesListener() {
    return new ZuulRefreshListener();
}

//内部静态类
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);
            }
        }
    }
    
}

ZuulProxyConfiguration中的监听:

//加载bean
@Bean
public ApplicationListener<ApplicationEvent> zuulDiscoveryRefreshRoutesListener() {
    return new ZuulDiscoveryRefreshListener();
}

//内部静态类
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);
    }
}

以上可以看出有个问题,两个地方都监听了HeartbeatEvent,并且做了相同的处理,会导致重复刷新

  • 触发心跳事件:SimpleApplicationEventMulticaster-->167行
  • 心跳是个线程池专门处理,初始化是在:com.netflix.discovery.DiscoveryClient-->1247行
  • 心跳的间隔时间配置有bug(配置没生效,配置的名称是间隔,但是线程池调度的时候传给超时时间的),默认是30分钟,配置是:
#org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean.leaseRenewalIntervalInSeconds
eureka.instance.leaseRenewalIntervalInSeconds=30

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
k8s与网络--Flannel源码分析
之前在k8s与网络--Flannel解读一文中,我们主要讲了Flannel整体的工作原理。今天主要针对Flannel v0.10.0版本进行源码分析。首先需要理解三个比较重要的概念: 网络(Network):整个集群中分配给 flannel 要管理的网络地址范围 子网(Subnet):flanne.
1638 0
元旦在家撸了两天Seata源码,你们是咋度过的呢?
2020年12月31日晚23点30分,我发了2020年的最后一个朋友圈:假期吃透Seata源码,有组队的吗?
23 0
Spring AOP 源码分析——创建代理对象
1.简介 与筛选合适的通知器相比,创建代理对象的过程则要简单不少,本文所分析的源码不过100行,相对比较简单。在接下里的章节中,我将会首先向大家介绍一些背景知识,然后再去分析源码。
1001 0
Spring IOC 容器源码分析
原文出处:https://javadoop.com/post/spring-ioc Spring 最重要的概念是 IOC 和 AOP,本篇文章其实就是要带领大家来分析下 Spring 的 IOC 容器。
700 0
只需4个步骤,分析解决在生产环境下JVM内存泄露问题
只需4个步骤,分析解决在生产环境下JVM内存泄露问题
4809 0
Dubbo 源码分析 - 集群容错之 Directory
1. 简介 前面文章分析了服务的导出与引用过程,从本篇文章开始,我将开始分析 Dubbo 集群容错方面的源码。这部分源码包含四个部分,分别是服务目录 Directory、服务路由 Router、集群 Cluster 和负载均衡 LoadBalance。
1019 0
机器学习实战:基于概率论的分类方法:朴素贝叶斯(源码解析,错误分析)
按照惯例,先把代码粘到这里 from numpy import * def LoadDataSet(): postingList = [['my', 'dog', 'has', 'flea', 'proble...
840 0
spring aop 注入源码解析
spring aop 注入源码解析
2004 0
+关注
7
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载