概述

  1. 解决什么问题

    • 微服务意味着要将单体应用中的业务拆分成一个个子服务,每个服务的粒度相对较小,因此系统中会出现大量的服务。由于每个服务都需要必要的配置信息才能运行,所以一套集中式的、动态的配置管理设施是必不可少的。
    • 我们写的每一个模块中都有application.yml配置文件,比如其中有数据库连接的配置当需要修改的时候,那么每一个配置文件都需要进行修改。所以需要一个配置中心来管理这些统一的配置
  2. 是什么

    • SpringCloud Config为微服务架构中的微服务提供集中化的外部配置支持,配置服务器为各个不同微服务应用的所有环境提供了一个中心化的外部配置。
  3. 结构

    • SpringCloud Config分为服务端和客户端两部分。

    • 服务端也称为分布式配置中心它是一个独立的微服务应用,用来连接配置服务器并为客户端提供获取配置信息,加密/解密信息等访问接口

    • 客户端(我们的微服务模块)则是通过指定的配置中心来管理应用资源,以及与业务相关的配置内容,并在启动的时候从配置中心获取和加载配置信息。

    • 配置服务器默认采用git来存储配置信息,这样就有助于对环境配置进行版本管理,并且可以通过git客户端工具来方便的管理和访问配置内容。

      一般运维人员通过配置服务器修改配置,然后我们的客户端通过配置中心(服务端)来获取公共的配置

SpringCloud Config配置中心 - 图1

  1. 作用

    • 集中管理配置文件
    • 不同环境不同配置,动态化的配置更新,分环境部署
    • 运行期间动态调整配置
    • 当配置发生改变时,服务不需要重启即可感知配置文件的变化并应用新的配置
    • 将配置信息以REST接口形式暴露

搭建配置服务器

  • 配置服务器默认使用git,所以我在Github创建了一个配置仓库并clone到本地

    SpringCloud Config配置中心 - 图2

SpringCloud Config配置中心 - 图3

提交配置文件到主分支

SpringCloud Config配置中心 - 图4

配置文件内容

以config-dev.yml为例

SpringCloud Config配置中心 - 图5

  • 为了演示后面的分支新建分支

    SpringCloud Config配置中心 - 图6

以config-dev.xml为例,内容如下

SpringCloud Config配置中心 - 图7

  • 使用过程中需要生成ssh key

    首先 创建key:ssh-keygen -t rsa -C "你的邮箱"这里生成的是OpenSSH Key

SpringCloud Config配置中心 - 图8

查看生成的SSHKey

SpringCloud Config配置中心 - 图9

但是SpringCloud Config不支持使用OpenSSH Key,否则会报错

SpringCloud Config配置中心 - 图10

所以需要生成RSA Key,命令如下ssh-keygen -t rsa -b 4096

SpringCloud Config配置中心 - 图11

此外,还需要在Github上配置SSHKey,注意这里添加的是公钥

SpringCloud Config配置中心 - 图12

SpringCloud Config配置中心 - 图13

测试

SpringCloud Config配置中心 - 图14

Config服务端配置

  1. 创建Module

  2. 修改pom文件

    1. <dependencies>
    2. <dependency>
    3. <groupId>org.springframework.cloud</groupId>
    4. <artifactId>spring-cloud-config-server</artifactId>
    5. </dependency>
    6. <dependency>
    7. <groupId>org.springframework.cloud</groupId>
    8. <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    9. </dependency>
    10. <dependency>
    11. <groupId>org.springframework.boot</groupId>
    12. <artifactId>spring-boot-starter-web</artifactId>
    13. </dependency>
    14. <dependency>
    15. <groupId>org.springframework.boot</groupId>
    16. <artifactId>spring-boot-starter-actuator</artifactId>
    17. </dependency>
    18. <dependency>
    19. <groupId>org.springframework.boot</groupId>
    20. <artifactId>spring-boot-devtools</artifactId>
    21. <scope>runtime</scope>
    22. <optional>true</optional>
    23. </dependency>
    24. <dependency>
    25. <groupId>org.projectlombok</groupId>
    26. <artifactId>lombok</artifactId>
    27. <optional>true</optional>
    28. </dependency>
    29. <dependency>
    30. <groupId>org.springframework.boot</groupId>
    31. <artifactId>spring-boot-starter-test</artifactId>
    32. <scope>test</scope>
    33. </dependency>
    34. </dependencies>
  1. 编写配置文件

    SpringCloud Config配置中心 - 图15

默认分支这里,不设置的话是master,由于我创建的仓库默认分支是main,所以必须设置

  1. 主启动类

    SpringCloud Config配置中心 - 图16

  1. 测试

    SpringCloud Config配置中心 - 图17

不带分支名访问,默认访问的分支是我在配置文件中配置的default-label

SpringCloud Config配置中心 - 图18

至此,服务端到配置服务器已经建立了连接

SpringCloud Config配置中心 - 图19

  1. 分支访问方式

    SpringCloud Config配置中心 - 图20

label表示分支

application表示配置文件名,比如配置文件config-dev.yml,那么application就是config

profile表示环境(dev,test,prod)

Config客户端配置

  • 客户端需要从配置中心获取公共配置,同时结合自己的配置一起组成客户端的配置

    SpringCloud Config配置中心 - 图21

  • 如何获取远端公共配置

    SpringCloud Config配置中心 - 图22

如果需要使用配置中心的配置,需要开启bootstrap并且提供bootstrap.yml配置文件

  • 关于bootstrap.yml

    applicaiton.yml是用户级的资源配置项

bootstrap.yml是系统级的,优先级更加高

Spring Cloud会创建一个“Bootstrap Context”,作为Spring应用的Application Context的父上下文。初始化的时候,Bootstrap Context负责从外部源加载配置属性并解析配置。这两个上下文共享一个从外部获取的Environment

Bootstrap属性有高优先级,默认情况下,它们不会被本地配置覆盖。 Bootstrap contextApplication Context有着不同的约定,所以新增了一个bootstrap.yml文件,保证Bootstrap ContextApplication Context配置的分离。

配置文件加载加载顺序:bootstrap.yml > application.yml > application-dev(prod).yml

  • 案例

    1. 创建Module

    2. 修改pom文件

      1. <dependencies>
      2. <!-- config -->
      3. <dependency>
      4. <groupId>org.springframework.cloud</groupId>
      5. <artifactId>spring-cloud-starter-config</artifactId>
      6. </dependency>
      7. <dependency>
      8. <groupId>org.springframework.cloud</groupId>
      9. <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
      10. </dependency>
      11. <dependency>
      12. <groupId>org.springframework.boot</groupId>
      13. <artifactId>spring-boot-starter-web</artifactId>
      14. </dependency>
      15. <dependency>
      16. <groupId>org.springframework.boot</groupId>
      17. <artifactId>spring-boot-starter-actuator</artifactId>
      18. </dependency>
      19. <dependency>
      20. <groupId>org.springframework.boot</groupId>
      21. <artifactId>spring-boot-devtools</artifactId>
      22. <scope>runtime</scope>
      23. <optional>true</optional>
      24. </dependency>
      25. <dependency>
      26. <groupId>org.projectlombok</groupId>
      27. <artifactId>lombok</artifactId>
      28. <optional>true</optional>
      29. </dependency>
      30. <dependency>
      31. <groupId>org.springframework.boot</groupId>
      32. <artifactId>spring-boot-starter-test</artifactId>
      33. <scope>test</scope>
      34. </dependency>
      35. </dependencies>
  1. 配置文件

    bootstrap.yml:系统级配置文件,从配置中心获取配置信息

SpringCloud Config配置中心 - 图23

application.yml用户级配置文件,可以写一写自定义的配置信息

SpringCloud Config配置中心 - 图24

  1. 主启动类

    注册到Eureka

SpringCloud Config配置中心 - 图25

  1. 业务类

    由于bootstrap.yml使用的是配置中心的配置,也即配置文件中会获得如下配置

SpringCloud Config配置中心 - 图26

获取配置文件中的配置信息

SpringCloud Config配置中心 - 图27

  1. 测试

    也就是说配置中心的配置信息已经加载到客户端了

SpringCloud Config配置中心 - 图28

  • 存在的问题:客户端不会动态刷新

    当配置服务器中的配置修改之后

SpringCloud Config配置中心 - 图29

服务端获取配置,发现配置已经更新

SpringCloud Config配置中心 - 图30

客户端获取配置信息,发现并未动态刷新

SpringCloud Config配置中心 - 图31
重启客户端之后,才将配置信息刷新

SpringCloud Config配置中心 - 图32

Config客户端动态刷新

  1. 客户端需要引入actuator依赖
    1. <dependency>
    2. <groupId>org.springframework.boot</groupId>
    3. <artifactId>spring-boot-starter-actuator</artifactId>
    4. </dependency>
  1. 对外暴露监控端口

    SpringCloud Config配置中心 - 图33

  1. 业务类添加注解

    标注@RefreshScope的Bean在运行时可以动态刷新,并且使用到这个Bean的组件将在下一次调用中获取一个新的实例,这个实例经过完整的初始化过程并且注入了所有的依赖

SpringCloud Config配置中心 - 图34

那么这个Controller就具有了动态刷新的能力

SpringCloud Config配置中心 - 图35

  1. 测试

    客户端启动之后,获取到的配置文件信息

SpringCloud Config配置中心 - 图36

配置服务器修改配置信息

SpringCloud Config配置中心 - 图37

客户端获取配置文件

SpringCloud Config配置中心 - 图38

  1. 还需要手动发送请求刷新客户端

    手动发送POST请求http://localhost:3355/actuator/refresh刷新客户端

SpringCloud Config配置中心 - 图39

再次刷新客户端

SpringCloud Config配置中心 - 图40

  1. 存在的问题

    • 如果有多个微服务都需要更新,那么岂不是每个微服务都需要去发送一个POST请求?
    • 能否通过广播的形式,一次通知,处处生效
    • 大范围的自动刷新,除去个别不刷新,能否实现?

消息总线(Bus)