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

请先阅读之前的内容:

  • Spring Cloud 学习笔记 - No.1 服务注册发现
  • Spring Cloud 学习笔记 - No.2 服务消费 Ribbon & Feign

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/

Spring Cloud 学习笔记 - No.3 分布式配置 Config_第1张图片
分布式配置中心

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

Spring Cloud 学习笔记 - No.3 分布式配置 Config_第2张图片
三个不同环境的配置文件

其中一个文件的内容如下 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 中导入了如下的依赖:


    org.springframework.cloud
    spring-cloud-starter-config



    org.springframework.cloud
    spring-cloud-config-server



    org.springframework.boot
    spring-boot-starter-actuator



    org.springframework.cloud
    spring-cloud-starter-netflix-eureka-client

随后在启动程序中通过 @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 中添加了如下的依赖:


    org.springframework.cloud
    spring-cloud-starter-config

随后创建 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 和一组感兴趣的事件,例如:


Spring Cloud 学习笔记 - No.3 分布式配置 Config_第3张图片
设置 Webhook

Spring Cloud 学习笔记 - No.3 分布式配置 Config_第4张图片
设置 Webhook

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

Spring Cloud 学习笔记 - No.3 分布式配置 Config_第5张图片
推送通知和 Spring Cloud Bus

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


    org.springframework.cloud
    spring-cloud-starter-bus-amqp



    org.springframework.cloud
    spring-cloud-config-monitor

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

spring.rabbitmq.host=127.0.0.1
Spring Cloud 学习笔记 - No.3 分布式配置 Config_第6张图片
启动两个 config-server 实例连接到 RabbitMQ

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


    org.springframework.cloud
    spring-cloud-starter-bus-amqp

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

spring.rabbitmq.host=127.0.0.1

拓展阅读

  • Spring Cloud构建微服务架构:分布式配置中心(加密与解密)
  • Spring Cloud构建微服务架构:分布式配置中心(高可用与动态刷新)

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

你可能感兴趣的:(Spring Cloud 学习笔记 - No.3 分布式配置 Config)