Spring Cloud 学习笔记 - No.3 分布式配置 Config

请先阅读之前的内容:

Spring Cloud Config 介绍

https://cloud.spring.io/spring-cloud-config/

Spring Cloud Config provides server and client-side support for externalized configuration in a distributed system.

Spring Cloud Config 是 Spring Cloud 团队创建的一个全新项目,用来为分布式系统中的基础设施和微服务应用提供集中化的和可扩展的外部配置支持

它分为服务端与客户端两个部分:

  • 服务端也称为分布式配置中心,它是一个独立的微服务应用,用来连接配置仓库(例如 Git)并为客户端提供获取配置信息、加密/解密信息等访问接口
  • 客户端则是微服务架构中的各个微服务应用或基础设施,它们通过指定的配置中心来管理应用资源与业务相关的配置内容,并在启动的时候从配置中心获取和加载配置信息。

Spring Cloud Config 实现了对服务端和客户端中环境变量 Environment 和属性配置 PropertySource 的抽象映射,所以它除了适用于Spring 构建的应用程序之外,也可以在任何其他语言运行的应用程序中使用。
由于 Spring Cloud Config 实现的配置中心默认采用 Git 来存储配置信息,所以使用 Spring Cloud Config构建的配置服务器,天然就支持对微服务应用配置信息的版本管理,并且可以通过 Git 客户端工具来方便的管理和访问配置内容。当然它也提供了对其他存储方式的支持,比如:SVN仓库、本地化文件系统。

一个分布式配置的场景

场景描述:我们有一个服务,部署在分布式的环境上,服务需要访问数据库。通常情况下,我们将数据库的配置(例如数据库地址,用户名,密码等等)以文件的形式放置在项目自身的目录中。
这样的问题是,假如配置发生了变化(例如数据库用户名改变了),我们需要修改配置文件,重新 Build,重新 Deploy。
现在我们尝试将配置文件放在第三方的位置,例如 Git。然后我们创建一个配置中心 config-server,它负责去 Git 仓库里读取文件内容。最后其他应用程序,例如之前创建的 eureka-consumer 通过配置中心 config-server 去读取配置。
在这里有一个问题,我们只创建了一个配置中心 config-server,这样的话,会出现单点失败,并且负载均衡得不到保障。
因此我们需要创建多个配置中心,即分布式配置中心,每一个 config-server 都会以服务的形式注册到之前创建的服务注册中心 eureka-server 中去。
结构如下:该图引用自 https://blog.csdn.net/fox9916/article/details/79499854/

分布式配置中心

首先我们在 Github 上创建一个 repo,位置:https://github.com/chenxiangcyr/spring-cloud-config-repo-demo。可以看到,包括三个不同环境的配置文件(开发,测试,生产):

三个不同环境的配置文件

其中一个文件的内容如下 demo-dev.properties

jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306
jdbc.username=rootDev
jdbc.password=rootDev

config-server 配置中心

通过的 Spring Assistant 插件来创建项目,具体过程不再赘述。
pom.xml 中导入了如下的依赖:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-config</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-config-server</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

随后在启动程序中通过 @EnableConfigServer 来开启 Spring Cloud Config 的服务端功能。:

@SpringBootApplication
@EnableConfigServer
@EnableDiscoveryClient
public class ConfigServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(ConfigServerApplication.class, args);
    }
}

随后在 application.properties 中添加配置服务的基本信息以及 Git 仓库的相关信息。

spring.application.name=config-server
server.port=4001

# 服务注册中心
eureka.client.serviceUrl.defaultZone=http://localhost:1234/eureka/

# Git仓库地址
spring.cloud.config.server.git.uri=https://github.com/chenxiangcyr/spring-cloud-config-repo-demo/

# 如果我们的Git仓库需要权限访问,那么可以通过配置下面的两个属性来实现
# spring.cloud.config.server.git.username=
# spring.cloud.config.server.git.password=

# 配置文件所在的目录
spring.cloud.config.server.git.search-paths=/**

# 配置文件所在的分支
spring.cloud.config.label=master

management.endpoints.web.exposure.include=*

最后我们分别以 4001 和 4002 两个端口来启动 config-server 配置中心,可以看到每一个 config-server 都会以服务的形式注册到之前创建的服务注册中心 eureka-server 中去,点击 http://127.0.0.1:1234/ 查看如下:

每一个 config-server 都会以服务的形式注册到之前创建的服务注册中心 eureka-server 中去

随后我们就可以通过浏览器等工具直接来访问到我们的配置内容了。访问配置信息的 URL 与配置文件的映射关系如下:

  • /{application}/{profile}/{label}
  • /{application}-{profile}.yml
  • /{label}/{application}-{profile}.yml
  • /{application}-{profile}.properties
  • /{label}/{application}-{profile}.properties

上面的 URL 会映射{application}-{profile}.properties对应的配置文件,其中 {label} 对应Git上不同的分支,默认为 master
例如我们通过 http://127.0.0.1:4001/demo/dev/ 的形式读取配置文件的具体内容:

{
    name: "demo", 
    profiles: [
        "dev"
    ], 
    label: null, 
    version: "92f9ab1bff77011b8ab16f0d2dc7e3f24e326f6d", 
    state: null, 
    propertySources: [
        {
            name: "https://github.com/chenxiangcyr/spring-cloud-config-repo-demo//demo-dev.properties", 
            source: {
                jdbc.driverClassName: "com.mysql.jdbc.Driver", 
                jdbc.url: "jdbc:mysql://127.0.0.1:3306", 
                jdbc.username: "rootDev", 
                jdbc.password: "rootDev"
            }
        }
    ]
}

获取配置信息

在这里,我们利用之前创建的项目 eureka-consumer,使得它可以通过分布式配置中心 config-server 来读取配置。
首先在 pom.xml 中添加了如下的依赖:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-config</artifactId>
</dependency>

随后创建 bootstrap.properties ,用来配置配置中心:

# 开启配置服务发现
spring.cloud.config.enabled=true

# 配置服务实例名称
spring.cloud.config.discovery.enabled=true
spring.cloud.config.discovery.service-id=config-server

spring.cloud.config.name=demo
spring.cloud.config.profile=dev
spring.cloud.config.label=master

eureka.client.serviceUrl.defaultZone=http://localhost:1234/eureka/

注意:上面这些属性必须配置在 bootstrap.properties 中,这样 config-server 中的配置信息才能被正确加载。

随后,我们创建一个新的 ReadConfigController 来通过 @Value 注解的形式读取配置:

@RestController
public class ReadConfigController {
    private final static Logger logger = LoggerFactory.getLogger(ReadConfigController.class);

    @Value("${jdbc.driverClassName}")
    String driverClassName;

    @Value("${jdbc.url}")
    String url;

    @Value("${jdbc.username}")
    String username;

    @Value("${jdbc.password}")
    String password;

    @GetMapping("/config")
    public String config() {

        logger.info("jdbc.driverClassName = " + driverClassName);
        logger.info("jdbc.url = " + url);
        logger.info("jdbc.username = " + username);
        logger.info("jdbc.password = " + password);

        return "success";
    }
}  

最后,重启 eureka-consumer,访问新创建的 Rest 接口 http://127.0.0.1:3001/config,可以在日志中看到,配置被成功读取:

配置被成功读取

推送通知和 Spring Cloud Bus

在上面的示例中,有一个问题:我们通过 Git 修改来 demo-dev.properties 文件中的内容,但是更新后的内容并没有被 eureka-consumer 获取到。

现在我们来解决这个问题:
许多源代码存储库提供程序(例如Github,Gitlab 或 Bitbucket)将通过 Webhook 通知您存储库中的更改。
可以通过提供商的用户界面将 Webhook 配置为 URL 和一组感兴趣的事件,例如:


设置 Webhook

设置 Webhook

流程如下图所示:引用自 https://blog.csdn.net/mazhen1991/article/details/78513452

推送通知和 Spring Cloud Bus

对于配置中心 config-server,需要进行如下修改
添加如下的依赖到 pom.xml 中:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-config-monitor</artifactId>
</dependency>

安装并启动一个 RabbitMQ 实例,并在 application.properties 中配置 RabbitMQ 连接信息:

spring.rabbitmq.host=127.0.0.1
启动两个 config-server 实例连接到 RabbitMQ

对于 eureka-consumer,需要进行如下修改
添加如下的依赖到 pom.xml 中:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>

application.properties 中配置 RabbitMQ 连接信息:

spring.rabbitmq.host=127.0.0.1

拓展阅读


引用:
程序猿DD Spring Cloud基础教程
Spring Cloud构建微服务架构:分布式配置中心【Dalston版】
Spring Cloud Dalston中文文档

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

推荐阅读更多精彩内容