Config组件
Config又称为统一配置中心。顾名思义,就是将配置统一管理。配置统一管理的好处是在日后大规模集群部署服务应用时相同的服务配置一致,日后再修改配置只需要统一修改全部同步,不需要一个一个服务手动维护。
Config服务中心开发
1. 配置
-
创建独立的config模块。
-
将模块注册入服务注册中心(本文以Consul为注册中心)。
-
模块引入依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-config-server</artifactId> </dependency>
-
模块启动类添加注解
@SpringBootApplication // 开启配置中心服务 @EnableConfigServer public class ConfigApplication { public static void main(String[] args) { SpringApplication.run(ConfigApplication.class, args); } }
-
在githhub上创建配置中心远程仓库
-
获取仓库地址
-
在模块中配置github仓库地址
spring: application: name: config cloud: # consul配置 consul: ... # config配置 config: server: git: uri: https://github.com/AydenBryan/config-springcloud-demo.git # 如果是私人仓库需要配置 # username: # password:
-
在github远程仓库中创建配置文件
-
本地拉取远程仓库中的配置文件(三种方式)
http://模块ip:模块port/products-xxx.properties http://模块ip:模块port/products-xxx.yml http://模块ip:模块port/products-xxx.json
-
查看拉取配置文件的详细信息(根据需要)
http://模块ip:模块port/products/xxx http://模块ip:模块port/products/dev http://模块ip:模块port/products/prod
注意:
-
在github上创建仓库时,会让你选择Public和Private。Public是公开仓库,Private是私人仓库。一般公司使用的都是私人仓库,私人仓库需要公司给你分配的用户名和密码才能访问,安全性高,但是需要付费才能使用。所以本文采用公开仓库作为配置中心仓库。
-
如果使用的私人仓库作为配置中心的远程仓库,那么
application.yml
文件中还需要配置username和password。 -
远程仓库存储的配置文件类型:properties,yml。
-
在配置中心拉取远程仓库的配置文件时,可以根据拉取请求中配置文件的后缀,来自动转换文件类型。但是文件类型只能在properties,yml,json之间切换。
-
在拉取请求中如果写
http://模块ip:模块port/products.properties
是拉取不到products配置文件的。因为Config注册中心对拉取请求中的配置文件名有规定的格式。该格式参考了配置文件分解和合并的原理。在真正的项目开发中,一个服务会运行在多种环境中,例如开发环境
dev
,生产环境prod
,测试环境test
等。该服务在每一种环境下,配置文件都是不一样的,体现在配置文件的公共配置一样,但是每个环境都有自己的特殊配置。因此衍生出了配置文件分解和合并的一种管理方案。例如products服务,
products.yml
就是该服务在不同环境下的公共配置,products-dev.yml
就是该服务在开发环境下的特殊配置,products-prod.yml
就是该服务在生产环境下的特殊配置。在Config组件中也同样支持该种管理方法,因此对于一个服务,我们可能会在github远程仓库中创建该服务的公共配置文件和各个环境下的特殊配置文件。假设以上三个文件都存在,这时拉取请求中如果写
http://模块ip:模块port/products-xxx.properties
如果products-xxx不能匹配远程仓库中任何一个文件,那么就会拉取
products.yml
文件。拉取请求中如果写http://模块ip:模块port/products-dev.properties
那么会把
products.yml
和products-dev.yml
一起拉下来。拉取请求中如果写http://模块ip:模块port/products-prod.properties
那么会把
products.yml
和products-prod.yml
一起拉下来。这种拉取规则大大减少了配置文件的配置冗余问题。
2. 指定本地仓库位置
-
在项目
resources
目录下创建localconfig
文件夹,并拷贝绝对路径。 -
配置
application.yml
# config配置 config: server: git: uri: https://gitee.com/aydenbryan/config-springcloud-demo.git # 本地仓库位置 basedir: G:\Project\springcloud\springcloud-demo-HoxtonSR6\config\src\main\resources\localconfig
注意:
localconfig
文件夹作为本地仓库必须是空文件夹,否则在第一次从远端仓库抓取配置文件到本地仓库时,就会强行清空本地仓库。
3. 指定分支抓取
当仓库中不止一个分支时,可以抓取指定分支下的配置文件。
-
如果没有分支,可以创建一个分支
-
配置
application.yml
# config配置 config: server: git: uri: https://gitee.com/aydenbryan/config-springcloud-demo.git # 指定分支 default-label: dev
注意:
- 在github中,在
main
分支下创建新分支,main
分支会将全部内容全部拷贝到新分支中。 - 如果不配置指定分支,那么默认分支为
main
。
Config客户端开发
该案例目的是将项目中products服务配置为Config客户端。
-
引入依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency>
-
在github上创建
products.yml
存放服务在不同环境下的公共配置 -
在github上创建
products-prod.yml
存放服务在生产环境下的特殊配置 -
在github上创建
products-dev.yml
存放服务在开发环境下的特殊配置 -
配置
bootstrap.yml
spring: cloud: config: discovery: # 开启配置中心查找 enabled: true # 配置中心的服务名 service-id: config # 指定分支 label: main # 指定配置文件 name: products # 指定配置文件的环境 profile: dev
注意:
-
所有Config客户端的
application.yml
都需要改成bootstrap.yml
。因为每一个Config客户端的配置一部分需要从配置中心拉取,一部分需要在本地配置。在配置中心的一部分配置需要通过本地配置的信息才能够在配置中心中找到。如果使用
application.yml
配置,application.yml
在服务启动时加载。那么在服务启动时,服务不会等待向配置中心拉取的那部分配置,启动时发现缺少配置,直接报错。如果使用
bootstrap.yml
配置,bootstrap.yml
在服务预启动时加载。那么在服务启动时,配置中心的那部分配置已经被拉取到服务中,正常启动。 -
因为原先使用
application.yml
进行本地配置,而因为项目服务启动需要应用名,所以需要把spring.application.name
要留在本地application.yml
中配置。而现在使用使用bootstrap.yml
进行本地配置,在项目预启动时,应用名从配置中心加载进入服务,所以可以把spring.application.name
放在远程仓库中配置。
刷新配置文件
1. 说明
当github远程仓库中的配置文件修改后,各个服务客户端的配置文件却不能自动刷新,从而导致使用到配置文件参数的相关代码也得不到刷新。只有重启服务重新访问配置中心,让配置中心向远程仓库再拉取一次配置文件后,才能更新。
然而,在生产环境中,微服务可能非常多。每次修改完远端配置之后,不可能对所有服务进行重新启动。这个时候需要让修改配置的服务能够刷新远端修改之后的配置,从而不要每次重启服务才能生效,进一步提高微服务系统的维护效率。在Spring Cloud中也为我们提供了手动刷新配置和自动刷新配置两种策略。
2. 手动刷新配置
-
Config客户端开启所有web端点(其中包括配置文件远程刷新的端点)
management: endpoints: web: exposure: include: "*"
-
配置注解实现该区域代码能够随着配置文件的刷新而刷新
@RestController // 实现代码随着配置文件刷新而刷新 @RefreshScope public class TestController { // 从配置文件中获取内容 @Value("${name}") private String name; /** * 测试远端配置是否刷新 * @return 端口信息 */ @GetMapping("/config/testName") public String testName() { return "名字是:" + name; } }
-
手动发送一个POST请求调用刷新配置接口
curl -X POST http://服务ip:服务port/actuator/refresh
注意:
- 手动配置刷新一次只能定向刷新某个服务端口的配置文件,而不能刷新集群服务。一般运维会写一个脚本,自动执行多个
crul
,才能实现集群服务的刷新。为了更简便的实现集群中所有端口配置文件的刷新,需要结合消息总线实现自动刷新配置。