SpringCloud 整合 Config 实现服务配置中心,实战讲解!
一、背景介绍
随着微服务数量的逐渐增多,因为每个服务都有自己的配置文件,每当要修改某个配置属性时,需要修改配置文件,然后重新发布服务。如果数量非常的多,人工进行运维操作会非常鸡肋,而且容易出错。
服务配置中心就是用来解决这种问题。
今天通过这篇文章,一起来了解一下相关的服务配置中心以及应用方式。
二、Config 简介
目前市场上开源的服务配置中心有很多,比如 Spring Cloud Config、阿里的 Nacos、携程的 Apollo 等,都可以用来为分布式系统中的微服务应用提供集中化的外部配置支持。其中 Spring Cloud Config 是 Spring Cloud 团队创建的一个全新项目,可以和 Spring 生态无缝衔接,下面以 Spring Cloud Config 为例,介绍一下配置中心相关的应用方式。
从架构角度看,配置中心分为服务端与客户端两个部分。其中服务端,也称为服务配置中心,它是一个独立的微服务应用,用来连接配置仓库并为客户端提供获取相关的配置信息等访问接口;而客户端,则是微服务架构中的各个微服务应用,它们通过指定的配置中心来管理应用资源与业务相关的配置内容,并在启动的时候从配置中心获取和加载配置信息。

下面我们通过具体实例,看看如何使用 Spring Cloud Config 构建服务配置中心。
三、方案实践
Spring Cloud Config 默认支持通过 Git 存放配置文件,当然也提供了对其他存储方式的支持,比如:SVN仓库。
下面我们以 Git 仓库为例,做一个演示。
3.1、准备配置仓库
首先,准备一个 git 仓库,可以在 gitee 或 github 上创建都可以,比如本文准备的仓库地址。
https://gitee.com/pzblogs/config-demo

为了演示加载不同环境的配置,我们分别创建两份配置文件config-client.properties
、config-client-dev.properties
。
config-client.properties
配置文件,内容如下:
blog.name=hello123
config-client-dev.properties
配置文件,内容如下:
blog.name=gogogo123
3.2、构建服务端
通过 Spring Cloud Config 来构建服务配置中心非常的简单,通过以下三步骤即可完成。
3.2.1、创建服务配置中心
首先创建一个 Spring Boot 工程,命名为config-server
,并在pom.xml
中引入相关的依赖内容,示例如下:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.4.RELEASE</version>
<relativePath/>
</parent>
<dependencies>
<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>Edgware.SR3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
3.2.2、开启配置中心功能
然后,创建一个服务启动类并添加@EnableConfigServer
,表示开启 Spring Cloud Config 的服务端功能。
@EnableConfigServer
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
3.2.3、配置远程仓库信息
接着,在application.properties
中配置远程仓库相关的信息,示例如下:
spring.application.name=config-server
server.port=9010
# 配置git仓库地址
spring.cloud.config.server.git.uri=https://gitee.com/pzblogs/config-demo
spring.cloud.config.server.git.username=
spring.cloud.config.server.git.password=
3.2.4、服务测试
最后,将服务启动,测试服务配置中心是否能成功读取 gitee 仓库中的配置文件信息。
git 仓库中的配置文件会自动与 url 建立映射关系,可以通过以下规则获取相关信息。
- /{application}/{profile}[/{label}]
- /{application}-{profile}.yml
- /{label}/{application}-{profile}.yml
- /{application}-{profile}.properties
- /{label}/{application}-{profile}.properties
上面的 url 会映射到{application}-{profile}.properties
对应的配置文件,其中{application}
对应配置文件名;{profile}
对应环境名,默认default
;{profile}
对应分支名,默认为master
。
例如,在浏览器上访问http://localhost:9010/config-client/dev/master
,不出意外的话,会得到类似于如下的信息。
{
"name": "config-client",
"profiles": [
"dev"
],
"label": "master",
"version": "6c276700a010e8e56cdccf173834450f4b3c1472",
"state": null,
"propertySources": [
{
"name": "https://gitee.com/pzblogs/config-demo/config-client-dev.properties",
"source": {
"blog.name": "gogogo123"
}
},
{
"name": "https://gitee.com/pzblogs/config-demo/config-client.properties",
"source": {
"blog.name": "hello123"
}
}
]
}
可以清晰的看到,Json 中返回了应用名:config-client,环境名:dev,分支名:master,以及 default 环境和 dev 环境的配置信息。
3.2、构建客户端
客户端的搭建同样也很简单,只需要三步即可完成。
3.2.1、创建 config 客户端
首先创建一个 Spring Boot 工程,命名为config-client
,并在pom.xml
中引入相关的依赖内容,示例如下:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.4.RELEASE</version>
<relativePath/>
</parent>
<dependencies>
<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>Edgware.SR3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
3.2.2、添加配置文件
此处需要两个配置文件,application.properties
和bootstrap.properties
。
application.properties
配置文件,内容如下:
spring.application.name=config-client
server.port=9011
bootstrap.properties
配置文件,内容如下:
# 设置服务配置中心地址
spring.cloud.config.uri=http://localhost:9010/
# 对应{application}部分
spring.cloud.config.name=config-client
# 对应{profile}部分
spring.cloud.config.profile=default
# 对应git的分支
spring.cloud.config.label=master
spring.cloud.config
相关的属性必须配置在bootstrap.properties
文件中,才能被正确加载。
3.2.3、编写配置读取接口
接着,创建一个服务启动类,并编写配置读取接口。
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
配置文件变量读取逻辑如下!
@RestController
public class HelloController {
@Value("${blog.name}")
private String name;
@RequestMapping("/hello")
public String hello() {
return name;
}
}
3.2.4、服务测试
最后,将客户端服务启动起来。在浏览器上访问http://localhost:9011/hello
,不出意外的话,会得到类似于如下的信息。
hello123
可以将spring.cloud.config.profile
属性值改成dev
,再次启动服务发起访问,会得到如下信息。
gogogo123
可以清晰的看到,客户端成功的从服务配置中心获取到相关的信息。
四、动态刷新
不知道大家有没有发现,当修改 git 仓库配置文件的时候,客户端读取的配置信息并没有发生变化。
例如,将config-client.properties
配置文件,内容如下:
blog.name=hello123456
在不重启服务的情况下,访问http://localhost:9011/hello
接口,返回的依然是hello123
。
这是因为客户端并不能主动感知到服务配置中心的变化,如果我们想要实时读取最新配置信息,那么客户端就需要主动去获取最新的配置信息。
如何主动获取呢?
客户端可以集成spring-boot-starter-actuator
工具,通过调用/refresh
接口开启自动更新配置信息。
具体实现过程如下!
4.1、添加依赖
首先,在客户端中添加 actuator 依赖库,这个工具在 Spring Boot 系列文章中介绍过,它是一个服务监控模块,可以监控程序在运行时的各种状态,其中就包括自动更新配置信息功能。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
4.2、关闭安全认证
因为 Spring Boot 1.5.X 以上版本,默认开通了安全认证,无法通过接口请求直接更新,因此需要在application.properties
配置文件中,将安全认证验证关闭掉。
# 关闭安全认证
management.security.enabled=false
4.3、开启更新机制
接着,我们还需要给加载变量的类添加RefreshScope
注解,它的作用是在收到配置刷新的时候,自动将新的配置变量更新到该类对应的字段中。
@RestController
@RefreshScope
public class HelloController {
@Value("${blog.name}")
private String name;
@RequestMapping("/hello")
public String hello() {
return name;
}
}
4.4、服务测试
最后,将客户端启动起来,修改 git 仓库配置文件中的变量值。
再然后,以 POST 方法请求客户端的/refresh
接口,示例如下:

成功之后,在浏览器中再次访问http://localhost:9011/hello
接口,不出意外的话,会返回最新的配置变量。

五、小结
最后总结一下,服务配置中心可以解决分布式环境下每个微服务配置文件变量不一致的问题,尤其是对于一些公共变量,可以通过配置中心来统一定义。
不过也会带来新的问题,当要更新客户端配置变量时,比如客户端很多很多,如果不想重启服务,按照上面的逻辑,相当于要把每一个的客户端的/refresh
接口都调用一遍,同样鸡肋。
再下篇文章中,我们会介绍通过引入 mq 来异步刷新所有的客户端/refresh
接口,进一步降低人工运维的成本。
六、参考
https://www.didispace.com/spring-cloud/spring-cloud-starter-dalston-3.html
http://www.ityouknow.com/springcloud/2017/05/23/springcloud-config-svn-refresh.html
作者:潘志的技术笔记
出处:https://pzblog.cn/
版权归作者所有,转载请注明出处
