分布式配置中心: Spring Cloud Config
Spring Cloud Config 是一种用来动态获取Git、SVN、本地的配置文件的一种工具
1.为何统一管理微服务配置
对于Spring Boot应用,我们可以将配置内容写入 application.yml
,设置多个profile,也可以用多个application-{profile}.properties
文件配置,并在启动时指定spring.profiles.active={profile}
来加载不同环境下的配置。
在Spring Cloud微服务架构中,这种方式未必适用,微服务架构对配置管理有着更高的要求,如:
集中管理:成百上千(可能没这么多)个微服务需要集中管理配置,否则维护困难、容易出错;
运行期动态调整:某些参数需要在应用运行时动态调整(如连接池大小、熔断阈值等),并且调整时不停止服务;
自动更新配置:微服务能够在配置发生变化是自动更新配置。
以上这些要求,传统方式是无法实现的,所以有必要借助一个通用的配置管理机制,通常使用配置服务器来管理配置。
2.Sping Cloud Config 介绍
Spring Cloud Config分为Config Server
和Config Client
两部分,为分布式系统外部化配置提供了支持。 Spring Cloud Config非常适合Spring应用程序,也能与其他编程语言编写的应用组合使用。
微服务在启动时,通过Config Client请求Config Server以获取配置内容,同时会缓存这些内容。
config-server 配置服务端,服务管理配置信息
config-client 客户端,客户端调用server端暴露接口获取配置信息
上图:
3.Config Server
Config Server是一个集中式、可扩展的配置服务器,它可以集中管理应用程序各个环境下的配置,默认使用Git存储配置内容。
3.1 创建Config Server
3.1.1 创建用于存放配置文件的git仓库,添加配置文件
service1.properties
profile=default-1.0
service1-dev.properties
profile=dev-1.0
service1-test.properties
profile=test-1.0
service1-pro.properties
profile=pro-1.0
3.1.2 创建一个Spring Boot应用config-server,添加spring-cloud-config-server依赖
dependencies {
compile('org.springframework.cloud:spring-cloud-config-server:1.4.1.RELEASE')
}
3.1.3 在启动类添加@EnableConfigServer注解
@EnableConfigServer
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
3.1.4 在application.yml中配置Git仓库地址
server:
port: 8181
spring:
application:
name: config-server
cloud:
config:
server:
git:
uri: https://github.com/Lessismoreputin/spring-cloud-config-repository
username:
password:
3.2 Config Server文件映射
3.2.1 配置文件映射关系
Config Server启动以后,我们可以通过它暴露的端点获取配置文件内容,http请求地址与配置文件映射关系如下:
# 映射{application}-{profile}.properties文件
/{application}/{profile}/[{label}]
/{label}/{application}-{profile}.properties
/{application}-{profile}.properties
/{label}/{application}-{profile}.yml
/{application}-{profile}.yml
{application}通常使用微服务名称,对应Git仓库中文件名的前缀;
{profile}对应{application}-后面的dev、pro、test等;
{label}对应Git仓库的分支名,默认为master。
4.Config Client
Config Client是Config Server的客户端,用于操作存储在Config Server中的配置内容。
4.1 创建Config Client
4.1.1 创建一个Spring Boot项目config-client,添加依赖
dependencies {
compile('org.springframework.boot:spring-boot-starter-web')
compile('org.springframework.boot:spring-boot-starter-actuator')
compile('org.springframework.cloud:spring-cloud-starter-config:1.4.1.RELEASE')
}
4.1.2 创建配置文件application.yml
通常情况下,Config Client作为微服务的一部分,微服务的spring.application.name属性值决定了Git仓库中配置文件的的文件名前缀,需要为哪个微服务提供配置文件,配置文件的文件名就需要以spring.application.name属性值作为前缀。
server:
port: 8282
spring:
application:
name: service1 # 对应config-server获取的配置文件的{application}
4.1.3 创建配置文件bootstrap.yml
Spring Boot应用程序启动时加载application.yml/application.properties。Spring Cloud中有“引导上下文”的概念,引导上下文加载bootstrap.yml/bootstrap.properties,而且具有更高的优先级,默认情况下bootstrap.yml/bootstrap.properties中的属性不能被覆盖。
spring:
application:
name: service1 # 对应config-server获取的配置文件的{application}
cloud:
config:
uri: http://localhost:8181 # 对应config-server地址,默认值http://localhost:8888
profile: pro # 对应config-server获取的配置文件的{profile}
label: master # 对应config-server获取的配置文件的{label},即Git仓库分支
4.1.4 编写测试用的Controller
@RestController
public class ConfigController {
@Value("${profile}")
private String profile;
@GetMapping("/profile")
public String profile(){
return this.profile;
}
}
4.2 测试验证
依次启动config-server:8181和config-client:8282,访问http://localhost:8282/profile,返回如下结果
pro-1.0
Config Client能够正常通过Config Server获取Git仓库中指定环境的配置内容。
5.Git仓库配置
Config Server的application.yml配置文件中,通过spring.cloud.config.server.git.uri指定Git仓库地址,实际上该属性的配置方式非常灵活,支持多种方式。
5.1 占位符
{application}、{profile}、{label}等占位符可以用于映射配置文件,还可以用于Config Server中配置Git仓库地址。
5.1.1 使用{application}指定Git仓库地址
Step 1:在Config Server中用{application}占位符的形式指定Git仓库地址
spring:
cloud:
config:
server:
git:
uri: https://github.com/Lessismoreputin/{application}
Step 2:在Config Client中修改spring.application.name=spring-cloud-config-repository
,因为建了一个Git仓库,这里简单起见,就不再创建新的Git仓库了。
spring:
application:
name: spring-cloud-config-repository
Step 3:在Git仓库中创建一个application-dev.yml的文件
profile: application-test
特别注意:用占位符的形式定义Git仓库地址时,配置文件的文件名必须为application*.yml
或application*.properties
。
Step 4:依次启动Config Server和Config Client,访问http://localhost:8282/profile,结果如下
application-test
6 配置规则详解
Config Client从Config Server中获取配置数据的流程:
1.Config Client 启动时,根据 bootstrap.properties 中配置的应用名称(application)、环境名(profile)和分支名(label),向 Config Server 请求获取配置数据;
2.Config Server 根据 Config Client 的请求及配置,从Git仓库(这里以Git为例)中查找符合的配置文件;
3.Config Server 将匹配到的Git仓库拉取到本地,并建立本地缓存;
4.Config Server 创建Spring的 ApplicationContext 实例,并根据拉取的配置文件, 填充配置信息,然后将该配置信息返回给 Config Client ;
5.Config Client 获取到 Config Server 返回的配置数据后,将这些配置数据加载到自己的上下文中。同时,因为这些配置数据的优先级高于本地Jar包中的配置,因此将不再加载本地的配置。
那么, Config Server 又是如何与Git仓库中的配置文件进行匹配的呢?通常,我们会为一个项目建立类似如下的配置文件:
mallweb.properties : 基础配置文件;
mallweb-dev.properties : 开发使用的配置文件;
mallweb-test.properties : 测试使用的配置文件;
mallweb-prod.properties : 生产环境使用的配置文件;
当我们访问 Config Server 的端点时,就会按照如下映射关系来匹配相应的配置文件:
/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties
上面的Url将会映射为格式为:{application}-{profile}.properties(yml)的配置文件。另外, label 则对应Git上分支名称,是一个可选参数,如果没有则为默认的 master 分支。
而 Config-Client 的 bootstrap.properties 配置对应如下:
spring.application.name application;
spring.cloud.config.profile profile;
spring.cloud.config.label label.
7.Config Server健康状况
Config Server自带了健康状况指示器,暴露的endpoint为/health,用于检查配置的仓库是否可用。
对于文中的Config Server,请求http://localhost:8181/health返回如下结果
{
"status": "UP"
}
Less is more.