Spring Cloud之配置中心

Spring Cloud Config是Spring Cloud提供的一个用来为分布式系统中的基础服务和微服务提供集中配置的项目。

1. 关于Spring Cloud Config

目前,基于SpringBoot配置的诸多分布式应用,大都把配置文件放在项目的目录下,但是随着节点增多,会带来配置文件管理复杂的问题。为了解决这个问题,可以使用Spring Cloud Config提供的中心化配置服务,其默认使用Git仓库来存储配置信息。简单的配置中心架构如下图所示:

image

从图中可以看出一个Spring Cloud Config应用主要包括以下三个实体:

  • Git Repo,存放配置文件。
  • Config Server,读取Git Repo下的配置文件,并以REST接口的形式供Client调用。
  • Client,客户端,读取配置的应用,可以理解为是你的具体应用。

接下来,我们将详细阐述如何构建一个基于Spring Cloud Config的分布式配置中心,并实现简单的客户端,让其能够实时读取最新的配置。

2. 创建配置文件Git仓库

首先新建一个Git仓库,可以是Github、阿里云、你的本地Git初始化、公司Gitlab等等都支持。为了模拟真实的项目迭代过程,这个仓库中有以下两个配置文件:

1
2
myconfig-dev.properties #测试环境的配置文件
myconfig-pro.properties #线上环境的配置文件

其中myconfig-dev.properties的加入:

1
fileName=develop

myconfig-pro.properties文件中加入:

1
fileName=product

然后把文件push到git远程。

3. 配置中心Config Server

3.1 添加依赖

创建一个最简单的Spring Cloud项目,并添加以下依赖:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<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-starter-eureka</artifactId>
</dependency>

加入eureka的目的是使注册中心服务化,防止注册中心与客户端的耦合性过高。

3.2 修改配置文件

修改Config Server工程的配置文件application.properties内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
#server info
server.port=9090
spring.application.name=CONFIG-SERVER
#config
#git仓库地址
spring.cloud.config.server.git.uri=https://code.aliyun.com/zhaoyh_code/spring-config-files.git
#git的账号密码
spring.cloud.config.server.git.username=XXXX
spring.cloud.config.server.git.password=XXXX
#eureka注册中心地址
eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/

3.3 激活Server

打开启动类,添加@EnableConfigServer注解,开启Spring Cloud Config的Server功能。

1
2
3
4
5
6
7
8
9
10
11
12
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;
@SpringBootApplication
@EnableConfigServer
public class SpringcloudConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(SpringcloudConfigServerApplication.class, args);
}
}

3.4 测试Server

启动Config Server的项目,端口为9090,就可以先在本地读取配置了。首先要弄清楚Config Server如何对我们Git仓库下的文件做映射,具体可以参照以下规则:

1
2
3
4
5
/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties

以本文的配置文件为例:

1
2
myconfig-dev.properties #测试环境的配置文件
myconfig-pro.properties #线上环境的配置文件

则访问的对应关系为:

1
2
3
application: myconfig
profile: dev/pro
label: master/someBranch

浏览器输入 http://localhost:9090/myconfig/dev 就可以查看myconfig-dev.properties的内容,返回的结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
"name": "myconfig",
"profiles": [
"dev"
],
"label": null,
"version": "b197087b41626b993782751ffd1c439925951809",
"state": null,
"propertySources": [
{
"name": "https://code.aliyun.com/zhaoyh_code/spring-config-files.git/myconfig-dev.properties",
"source": {
"fileName": "develop"
}
}
]
}

可以看到该JSON中返回了应用名:myconfig,环境名:dev,和dev环境的配置内容。

4. 配置中心Client

创建一个空的Spring Cloud项目,或者是你之前就存在的Spring Cloud项目。

4.1 添加依赖

添加以下依赖:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<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-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>

4.2 配置文件

一共需要两个配置文件,application.properties和bootstrap.properties,至于什么是bootstrap.properties,官方是这么说的:

Bootstrap.yml (bootstrap.properties) is loaded before application.yml (application.properties),it’s like application.yml but for the bootstrap phase of an application context.

简单翻译一下就是在application.properties之前加载,且用于程序上下文的引导阶段。

application.properties的内容如下:

1
2
3
4
5
6
#server
server.port=9091
management.security.enabled=false
#name
spring.application.name=CONFIG_CLIENT

bootstrap.properties的内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#声明用那个application
spring.cloud.config.name=myconfig
#声明profile环境
spring.cloud.config.profile=dev
#声明Git的label
spring.cloud.config.label=master
#配置中心
spring.cloud.config.discovery.enabled=true
spring.cloud.config.discovery.serviceId=CONFIG-SERVER
#eureka注册中心
eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/

4.3 添加controller并测试

添加一个controler用于测试配置内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* Created by zhaoyh on 2018/1/18
* @author zhaoyh
*/
@RestController
@RefreshScope
public class MainController {
@Value("${fileName}")
private String fileName;
@RequestMapping(value = "/")
public String getName() {
return fileName;
}
}

只是一个很简单的读取fileName并返回的例子。启动类中不需要额外的注解,直接启动,访问: http://localhost:9091/ ,如果能成功看到fileName的结果,就说明客户端Client的实例就运行成功了。

4.4 配置热更新

项目运行过程中,不可避免的会对配置进行更改,假如我们此时修改myconfig-dev.properties的内容,并push提交,刷新 http://localhost:9091/ 后,看到的还是旧的配置,客户端该如何感知这种变化并能热更新配置内容呢,此时就需要加入refresh机制。

首先在需要配置内容的类上,加入@RefreshScope注解:

1
2
3
4
5
6
7
8
9
10
11
12
13
@RestController
@RefreshScope
public class MainController {
@Value("${fileName}")
private String fileName;
@RequestMapping(value = "/")
public String getName() {
return fileName;
}
}

启动客户端Client后,如果此时你的配置内容有了更新,在git上提交后,需要通知以下客户端,发送一个post请求即可:

1
curl -X POST 'http://localhost:9091/refresh'

再刷新客户端就会看到已经读取了最新的配置内容。每次更新配置内容后,需要手动的提醒客户端Client来刷新,因此你可以写一个脚本,在git提交后,发出post请求,这样也能相对地减少一些工作量。如果你使用Github管理配置文件,也可以设置webhook,设置相应的post请求。

以上内容就是关于Spring Cloud微服务框架之配置中心的全部内容了,谢谢你阅读到了这里!

Author:zhaoyh