Spring Cloud Config是用来为分布式系统中的基础设施和微服务应用提供集中化的外部配置支持的。
它由服务端和客户端构成:
其中,服务端也称为分布式配置中心,是一个独立的微服务应用,用来连接配置仓库、为客户端提供支持;
客户端则一般是各个微服务应用本身,它们通过指定服务端来管理自身的配置。
Spring Cloud Config默认支持Git作为配置仓库,存储各个微服务的配置信息,同时也能支持其他的存储方式,如:码云、SVN、本地化文件系统。
使用码云仓库作为“配置文件管理中心”,对配置文件进行统一管理。
创建码云账号,并新建仓库springcloud-config,可以设置为私密库
安装git,并配置码云账户信息
使用git,拉取仓库,在仓库中创建配置文件后,提交新建的配置文件信息到码云仓库
config-dev.yml
config:info: "master branch,springcloud-config/config-dev.yml version=1"
config-prod.yml
config:info: "master branch,springcloud-config/config-prod.yml version=1"
config-test.yml
config:info: "master branch,springcloud-config/config-test.yml version=1"
idea集成git
创建module,添加配置中心的核心pom引用
org.springframework.cloud spring-cloud-config-server org.springframework.cloud spring-cloud-starter-netflix-eureka-client org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-actuator org.springframework.boot spring-boot-devtools runtime true org.projectlombok lombok true org.springframework.boot spring-boot-starter-test test
@SpringBootApplication
@EnableConfigServer
public class MainAppConfigCenter3344 {public static void main(String[] args) {SpringApplication.run(MainAppConfigCenter3344.class,args);}
}
server:port: 3344spring:application:name: cloud-config-center #注册进Eureka服务器的微服务名cloud:config:server:git:uri: https://gitee.com/qianghao/springcloud-config.git #GitHub上面的git仓库名字####搜索目录search-paths:- springcloud-configusername: 你的码云账号password: 你的码云密码label: master#服务注册到eureka地址
eureka:client:service-url:defaultZone: http://eureka-server-7001:7001/eureka/
127.0.0.1 config-3344.com
测试:
1. 新建客户端功能测试module:cloud-config-client-3355
2. 引入配置中心客户端的核心依赖:spring-cloud-starter-config
org.springframework.cloud spring-cloud-starter-config org.springframework.cloud spring-cloud-starter-netflix-eureka-client org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-actuator org.springframework.boot spring-boot-devtools runtime true org.projectlombok lombok true org.springframework.boot spring-boot-starter-test test
3. 创建系统级配置文件bootstrap.yaml
这里需要引入一个新的概念:系统级的资源配置项 - bootstrap.yaml
3.1. 加载顺序
若application.yml 和bootstrap.yml 在同一目录下:bootstrap.yml 先加载 application.yml后加载
bootstrap.yml 用于应用程序上下文的引导阶段。bootstrap.yml 由父Spring ApplicationContext加载。
3.2. 配置区别
bootstrap是spring cloud的配置上下文加载。由spring-cloud-content包加载。
bootstrap.yml 和 application.yml 都可以用来配置参数。
bootstrap.yml 用来程序引导时执行,应用于更加早期配置信息读取。可以理解成系统级别的一些参数配置,这些参数一般是不会变动的。一旦bootStrap.yml 被加载,则内容不会被覆盖。
application.yml 可以用来定义应用级别的, 应用程序特有配置信息,可以用来配置后续各个模块中需使用的公共参数等。
3.3. 属性覆盖问题
启动上下文时,Spring Cloud 会创建一个 Bootstrap Context,作为 Spring 应用的 Application Context 的父上下文。
初始化的时候,Bootstrap Context 负责从 外部源 加载 配置属性 并 解析配置。这两个上下文共享一个从外部获取的 Environment。Bootstrap 属性有高优先级,默认情况下,它们不会被本地配置覆盖。
也就是说如果加载的 application.yml 的内容标签与 bootstrap 的标签一致,application 也不会覆盖 bootstrap,而 application.yml 里面的内容可以动态替换。
4. 因此我们需要从外部文件获取配置信息时,使用bootstrap.yaml就非常必要了。
创建bootstrap.yaml并写入以下配置:
server:port: 3355spring:application:name: config-clientcloud:#Config客户端配置config:label: master #分支名称name: config #配置文件名称profile: dev #读取后缀名称 上述3个综合:master分支上config-dev.yml的配置文件被读取http://config-3344.com:3344/master/config-dev.ymluri: http://config-3344.com:3344 #配置中心地址k#服务注册到eureka地址
eureka:client:service-url:defaultZone: http://eureka-server-7001:7001/eureka/
5. 配置主启动类
@SpringBootApplication
@EnableEurekaClient
public class ConfigClientMain3355 {public static void main(String[] args) {SpringApplication.run(ConfigClientMain3355.class,args);}
}
6. 编写业务类,获取配置信息
@RestController
public class ConfigClientController {@Value("${config.info}")private String configInfo;@GetMapping("/configInfo")private String getConfigInfo(){return configInfo;}
}
7. 测试获取配置信息:http://localhost:3355/configInfo
从上面bootstrap.yaml的介绍可以知道,它的优先级比较高,配置信息加载后一般是不会被覆盖,比如:
如果需要重新加载配置信息就需要重新启动服务,这是非常不友好的。这时我们就需要一种可以动态刷新配置的方法 - actuator监控服务。
org.springframework.boot spring-boot-starter-actuator
# 暴露监控端点
management:endpoints:web:exposure:include: "*"
@RestController
@RefreshScope
public class ConfigClientController {@Value("${config.info}")private String configInfo;@GetMapping("/configInfo")private String getConfigInfo(){return configInfo;}
}
curl -X POST "http://localhost:3355/actuator/refresh
测试:修改码云上的配置文件内容,并提交修改。然后发送post请求进行刷新,之后就可以获取最新的配置文件信息
现在产生了新的问题:
假如有多个微服务客户端3355/3366/3377怎么办?难道每个微服务都要进行请求刷新一次?
可否广播,一次通知,处处生效? Bus消息总线就可以实现