配置中心Config
配置中心Config
随着项目日益庞大,每个项目都散落着各种配置文件,如果采用分布式的开发模式,需要的配置文件随着服务增加而不断增多。某一个基础服务信息变更,都会引起一系列的更新和重启,运维苦不堪言也容易出错。配置中心就是是解决此类问题的。
市面上开源的配置中心有很多,BAT每家都出过,360的QConf、淘宝的diamond、百度的disconf都是解决这类问题。国外也有很多开源的配置中心Apache Commons Configuration、owner、cfg4j等等。
Spring Cloud Config
为分布式系统中的基础设施和微服务应用提供集中化的外部配置支持,它分为服务端与客户端两个部分。其中服务端也称为分布式配置中心,它是一个独立的微服务应用,用来连接配置仓库并为客户端提供获取配置信息、加密 / 解密信息等访问接口;而客户端则是微服务架构中的各个微服务应用或基础设施,它们通过指定的配置中心来管理应用资源与业务相关的配置内容,并在启动的时候从配置中心获取和加载配置信息。
由于 Spring Cloud Config 实现的配置中心默认采用 Git 来存储配置信息,所以使用 Spring Cloud Config 构建的配置服务器,天然就支持对微服务应用配置信息的版本管理,并且可以通过 Git 客户端工具来方便的管理和访问配置内容。当然它也提供了对其他存储方式的支持,比如:SVN 仓库、本地化文件系统。
Config Server
pom.xml中引入spring-cloud-config-server
依赖,完整依赖配置如下:
`<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.3.5.RELEASE</version> <relativePath/> <!-- lookup parent from repository --></parent><dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-config-server</artifactId> </dependency></dependencies><dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Brixton.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies></dependencyManagement>`
创建Spring Boot的程序主类,并添加@EnableConfigServer
注解,开启Config Server
@EnableConfigServer
@SpringBootApplication
public class Application {
public static void main(String[] args) {
new SpringApplicationBuilder(Application.class).web(true).run(args);
}
}
application.properties`中配置服务信息以及git信息,例如:
spring.application.name=config-server
server.port=8769
# git管理配置
spring.cloud.config.server.git.uri= http://admin@192.168.1.131:10010/r/v.git
#spring.cloud.config.server.git.searchPaths=config-repo
spring.cloud.config.server.git.username=username
spring.cloud.config.server.git.password=password
- spring.cloud.config.server.git.uri:配置git仓库位置
- spring.cloud.config.server.git.searchPaths:配置仓库路径下的相对搜索位置,可以配置多个,用,分割
- spring.cloud.config.server.git.username:访问git仓库的用户名
- spring.cloud.config.server.git.password:访问git仓库的用户密码
Spring Cloud Config也提供本地存储配置方式。我们只需要设置属性spring.profiles.active=native,Config Server会默认从应用的src/main/resource目录下检索配置文件。也可以通过spring.cloud.config.server.native.searchLocations=file:F:/properties/属性来指定配置文件的位置。
准备一个 Git 仓库,在 上面创建了一个文件夹 config-repo 用来存放配置文件,为了模拟生产环境,我们创建以下三个配置文件:
//默认
application.properties
// 开发环境
application-dev.yml
// 测试环境
application-test.yml
// 生产环境
application-prod.yml
其中设置了一个from属性,为每个配置文件分别设置了不同的值,如:
from=git-default-1.0
from=git-dev-1.0
from=git-test-1.0
from=git-prod-1.0
为了测试版本控制,在master中,我们都加入1.0的后缀,同时创建一个config-label-test分支,并将各配置文件中的值用2.0作为后缀。
URL与配置文件的映射关系如下:
/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties
/ { 应用名 } / { 环境名 } [ / { 分支名 } ]
/ { 应用名 } - { 环境名 }.yml
/ { 分支名 } / { 应用名 } - { 环境名 }.yml
/ { 应用名 } - { 环境名 }.properties
/ { 分支名 } / { 应用名 } - { 环境名 }.properties
上面的url会映射{application}-{profile}.properties
** 对应的配置文件,{label}
对应git上不同的分支,默认为master。先找给定名称的配置文件,如果找不到去application.yml/application.properties找
尝试构造不同的url来访问不同的配置内容,比如:要访问config-label-test分支,应用的prod环境,可以通过这个url:http://localhost:7001/application/prod/config-label-test
{
"name": "application",
"profiles": [
"prod"
],
"label": "config-label-test",
"version": "19de8a25575a7054a34230f74a22aa7f5575a9d1",
"propertySources": [
{
"name": "http://admin@192.168.1.131:10010/r/v.git/config-repo/didispace-prod.properties",
"source": {
"from": "git-prod-2.0"
}
},
{
"name": "http://admin@192.168.1.131:10010/r/v.git/config-repo/didispace.properties",
"source": {
"from": "git-default-2.0"
}
}
]
}
Config Client
创建一个Spring Boot应用,在pom.xml中引入spring-cloud-starter-config依赖,完整依赖关系如下:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Brixton.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
- 创建最基本的Spring Boot启动主类
@SpringBootApplication
public class Application {
public static void main(String[] args) {
new SpringApplicationBuilder(Application.class).web(true).run(args);
}
}
- 创建
bootstrap.properties
配置,来指定config server,例如:
spring.application.name=application
spring.cloud.config.profile=dev
spring.cloud.config.label=master
spring.cloud.config.uri=http://localhost:8769/
server.port=6020
- spring.application.name:对应前配置文件中的{application}部分
- spring.cloud.config.profile:对应前配置文件中的{profile}部分
- spring.cloud.config.label:对应前配置文件的git分支
- spring.cloud.config.uri:配置中心的地址
搭建srpingcloud-config server端,配置文件可以用application.yml 或 application.properties,config client端却要使用bootstrap.yml或bootstrap.properties。
格外注意(config client端):上面这些属性必须配置在bootstrap.properties中,config部分内容才能被正确加载。因为config的相关配置会先于application.properties,而bootstrap.properties的加载也是先于application.properties(bootstrap.yml 的加载也是先于 application.yml)。
创建一个Rest Api来返回配置中心的from属性,具体如下:
@RestController
class TestController {
@Value("${from}")
private String from;
@RequestMapping("/from")
public String from() {
return this.from;
}
}
启动该应用,并访问:http://localhost:6020/from ,我们就可以根据配置内容输出对应环境的from内容了。
配置刷新
有时,我们需要对配置内容做一些实时更新。server端会自动读取最新提交的内容,client端不会自动获取新的信息。
将config-server和config-client都启动起来,并访问客户端提供的REST API http://localhost:6020/from
来获取配置信息,可以获得返回内容为:git-dev-1.0
。接着,我们可以尝试使用Git工具修改当前配置的内容,比如,将config-repo/application-dev.properties
中的from的值从from=git-dev-1.0
修改为from=git-dev-2.0
,再访问http://localhost:6020/from
,可以看到其返回内容还是git-dev-1.0
。
下面进行改造:在config-client端增加一些内容和操作以实现配置的刷新
在config-clinet的pom.xml
中新增spring-boot-starter-actuator
监控模块,其中包含了/refresh
刷新API。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
增加spring-boot-starter-actuator包,这是一套监控的功能,可以监控程序在运行时状态,其中就包括
/actuator/refresh`的功能。
开启更新机制
需要给加载变量的类上面加载@RefreshScope
,在客户端执行/actuator/refresh
的时候就会更新此类下面的变量值。
@RefreshScope
@RestController
class TestController {
@Value("${from}")
private String from;
@RequestMapping("/from")
public String from() {
return this.from;
}
}
Spring Boot 1.5.X 以上默认开通了安全认证,所以要在配置文件 application.yml 中添加以下配置以将/actuator/refresh
这个 Endpoint 暴露出来
management:
endpoints:
web:
exposure:
include: refresh
改造完之后,我们以 POST 请求的方式来访问 http://localhost:6020/actuator/refresh 就会更新配置文件至最新版本。
Config Server中的加载顺序
加载 bootstrap. ------>连接config server 加载远程设置 --------> 加载application.的配置**
bootstrap 放一些你不想改的值
本地配置和远程配置冲突 以远程的为准