SpringCloud源码--SpringCloudConfig工作流程

首先,我是前端 转 PHP 转 JAVA 的以为小白,文中讲的不对的地方请提出来,也欢迎来喷

起因是我司使用Eureka注册中心和 Configserver配置中心来达到多服务共享配置的问题,我好奇是如何从配置中心获取配置后,将配置写入消费方的。
这便引发了我4个小时追代码的过程


Eureka

废话不多说,首先说说Eureka是个什么东西,其实我也不知道是啥!
首先先上一张看不懂的图片,好吧我承认,这是我看过理解最快的一张图片了

image.png

EurekaNetflix 开发的,一个基于 REST 服务的,服务注册与发现的组件

它主要包括两个组件:Eureka Server 和 Eureka Client

  • Eureka Client:一个Java客户端,用于简化与 Eureka Server 的交互(通常就是微服务中的客户端和服务端)
  • Eureka Server:提供服务注册和发现的能力(通常就是微服务中的注册中心)

各个微服务启动时,会通过 Eureka Client 向 Eureka Server 注册自己,Eureka Server 会存储该服务的信息

也就是说,每个微服务的客户端和服务端,都会注册到 Eureka Server,这就衍生出了微服务相互识别的话题

  • 同步:每个 Eureka Server 同时也是 Eureka Client(逻辑上的)
       多个 Eureka Server 之间通过复制的方式完成服务注册表的同步,形成 Eureka 的高可用
  • 识别:Eureka Client 会缓存 Eureka Server 中的信息
       即使所有 Eureka Server 节点都宕掉,服务消费者仍可使用缓存中的信息找到服务提供者(笔者已亲测)
  • 续约:微服务会周期性(默认30s)地向 Eureka Server 发送心跳以Renew(续约)信息(类似于heartbeat)
  • 续期:Eureka Server 会定期(默认60s)执行一次失效服务检测功能
       它会检查超过一定时间(默认90s)没有Renew的微服务,发现则会注销该微服务节点

Spring Cloud 已经把 Eureka 集成在其子项目 Spring Cloud Netflix 里面

以上都是拷贝的,说白了,Eureka做的就是接口转发的概念


SpringCloudConfig

Spring Cloud Config 的官方介绍文档地址如下:
https://cloud.spring.io/spring-cloud-static/Finchley.RELEASE/single/spring-cloud.html#_spring_cloud_config

英语好的自己读吧,我是懒得看

大致意思是,Spring Cloud Config 提供一种基于客户端与服务端(C/S)模式的分布式的配置管理。我们可以把我们的配置管理在我们的应用之外(config server 端),并且可以在外部对配置进行不同环境的管理,比如开发/测试/生产环境隔离,并且还能够做到实时更新配置。


现在要看是追源码了!!!

首先,配置文件中找到了Eureka的配置项

spring.application.name=quickstart-sample
eureka.client.serviceUrl.defaultZone=${QUICKSTART_EUREKAS:http://${QUICKSTART_USERNAME:admin}:${QUICKSTART_PASSWORD:123123}@localhost:20000/eureka/}
spring.cloud.config.profile=framework,test
spring.cloud.config.label=development-wayne
spring.cloud.config.discovery.enabled=true
spring.cloud.config.discovery.serviceId=configserver
spring.cloud.config.username=${QUICKSTART_USERNAME:admin}
spring.cloud.config.password=${QUICKSTART_PASSWORD:123123}

找到这些,我依旧是一头雾水,好吧,我自闭了~~我想放弃了~
开了15分钟小差,我决定从Maven包下手

在项目中找到spring-cloud-config-client-2.1.0.RELEASE.jar这个JAR包,并随便打开一个文件下载源码(听起来好高大上,我大PHP直接看vendor什么时候还要下载源码,哼~~)

全局搜索serviceId

image.png

看,这里有用到诶!!
那既然有 set 那就一定有 get,我继续找下去,找到getServiceId()的调用方出现了
image.png

无意间看了眼上面,嗯~~ 我猜这应该是心跳吧,他是定时的从配置中心获取配置。

继续走~


在源码的127行我发现了this.config.setUri(uri)字眼,无奈的看了下下面只剩下catch了,算了,就研究这个config吧!
image.png

一样的思维,有set 就一定有 get
image.png

在这里我找到了最终获取数据的地方

response = restTemplate.exchange(uri + path, HttpMethod.GET, entity,
                        Environment.class, args);

接下来就涉及到返回数据的地方了,转眼到spring-cloud-config-server-2.1.0.RELEASE.jar这个包中,我们可以看到SpringCloudConfig定义了一个名为EnvironmentController这样的控制器。

在控制器中我们找到了根据上面uri + path的方式请求的入口,

@RequestMapping("/{name}/{profiles}/{label:.*}")
    public Environment labelled(@PathVariable String name, @PathVariable String profiles,
            @PathVariable String label) {
        if (name != null && name.contains("(_)")) {
            // "(_)" is uncommon in a git repo name, but "/" cannot be matched
            // by Spring MVC
            name = name.replace("(_)", "/");
        }
        if (label != null && label.contains("(_)")) {
            // "(_)" is uncommon in a git branch name, but "/" cannot be matched
            // by Spring MVC
            label = label.replace("(_)", "/");
        }
        Environment environment = this.repository.findOne(name, profiles, label);
        if(!acceptEmpty && (environment == null || environment.getPropertySources().isEmpty())){
             throw new EnvironmentNotFoundException("Profile Not found");
        }
        return environment;
    }

我这里在配置文件中设置了spring.cloud.config.server.jdbc=true所以我这里是走的数据库,还有其他的读取配置方式,可自行查阅
根绝我设置的jdbc方式
上面的findOne使用了JdbcEnvironmentRepository中的实现方式
最后在第95行找到了

Map<String, String> next = (Map<String, String>) jdbc.query(this.sql,
                        new Object[] { app, env, label }, this.extractor);

这里的sql可通过配置spring.cloud.config.server.jdbc.sql进行复写
如果没有复写,那么就使用JdbcEnvironmentProperties中默认的SQL语句SELECT KEY, VALUE from PROPERTIES where APPLICATION=? and PROFILE=? and LABEL=?

好了,configserver完成了他的任务(东西好少啊,感觉很容易就找到了)。回过头,我们又要看消费方拿到了返回值做了些什么!!

ConfigServicePropertySourceLocator文件中我们看到,其实configserver做了一个拦截,在启动的时候把配置写了进去

在同文件104行终于找到了最后的方法,通过CompositePropertySource将配置加载到程序中

for (PropertySource source : result.getPropertySources()) {
    @SuppressWarnings("unchecked")
    Map<String, Object> map = (Map<String, Object>) source
                            .getSource();
    composite.addPropertySource(new MapPropertySource(source.getName(), map));
}

其实我想追一下CompositePropertySource的源码,但是我饿~~~~~~了,
第一次写看源码的笔记,可能有些地方我自己懂了就跳过了,如果哪里没写出来,欢迎提出来

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,874评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,102评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,676评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,911评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,937评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,935评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,860评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,660评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,113评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,363评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,506评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,238评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,861评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,486评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,674评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,513评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,426评论 2 352

推荐阅读更多精彩内容