目录
2. 通过 @ConfigurationProperties 注入
模块简介
配置中心模块是 Spring Cloud Tencent 最核心的模块之一,实现了 Spring Cloud PropertySourceLocator SPI 接口(PolarisConfigFileLocator.java)。
在应用启动 Bootstrap 阶段,Spring Cloud 会调用 PolarisConfigFileLocator 从 Polaris 服务端获取配置文件并加载到 Spring 上下文里。通过 Spring Boot 标准的 @Value,@ConfigurationProperties 注解即可获取配置内容。
动态配置刷新能力,1.6.0 版本之前通过 Spring Cloud 标准的 @RefreshScope 机制实现。 1.6.0 版本之后,通过反射的方式实现。反射的方式不用重新构建 bean 对象,影响面更小、性能更优。 (我们使用的是 1.9.1-2021.0.5 )
注意:
由于 Spring Cloud PropertySourceLoader SPI 是在 Bootstrap 阶段调用,所以 Polaris Config 相关的配置内容(例如Polaris 服务地址)需要放在 bootstrap.yml 文件里,而不能放在 application.yml 文件里,否则会初始化失败。
如果开发者原本的服务名( spring.application.name )配置在 application.yml 、application-*.yml 、application.properties 或 application-*.properties 内,使用 Spring Cloud Tencent Config 的功能时,需要将 spring.application.name 配置在 bootstrap.yml 内,或者在 bootstrap.yml 手动配置 spring.cloud.polaris.service 以指定文件分组名。
快速入门
本章节将介绍如何在 Spring Cloud 项目中使用 Spring Cloud Tencent Config 的功能。
完整 Example 代码请参考:polaris-config-example
第一步:引入 Polaris 服务端
请参考 安装北极星服务端
第二步:引入动态配置依赖
-
参考 Spring Cloud Tencent 版本管理 文档获取最新的版本号,引入 Spring Cloud Tencent Bom。
注意: Spring Cloud 、 Spring Boot 、 Spring Framework 之间有严格的版本对应关系,在 Spring Cloud Tencent 版本管理 文档中有详细罗列版本兼容性关系。请您在引入 Spring Cloud Tencent 版本时,根据项目 Spring Boot 和 Spring Framework 的版本,选择合适的 Spring Cloud Tencent 版本。
例如:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-tencent-dependencies</artifactId>
<version>1.8.2-Hoxton.SR9</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
2. 引入 Spring Cloud Tencent Config Starter
方式一:只引入 spring-cloud-starter-tencent-polaris-config
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-starter-tencent-polaris-config</artifactId>
</dependency>
方式二:通过 spring-cloud-starter-tencent-all 引入 sct 所有 starters
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-starter-tencent-all</artifactId>
<!-- 注意需要指定 type=pom-->
<type>pom</type>
</dependency>
如果使用 Spring Cloud 2021 版本,还需要添加如下依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
第三步:增加相关配置文件
在您项目的 bootstrap.yml 配置文件中加入以下配置内容,注意一定要放在 bootstrap.yml 里。因为应用启动强依赖配置,所以 Spring Cloud Config 是在 Bootstrap 阶段加载配置文件,所以需要把北极星相关的配置放在 bootstrap.yml 里。
bootstrap.yml 核心配置内容为配置北极星服务端地址以及注入的配置文件信息。
1. 配置 Polaris 配置中心地址
如果您使用的北极星配置中心和注册中心是同一套北极星集群,则只需配置 spring.cloud.polaris.address 即可。
如果您部署了两套北极星集群,分别用于注册中心和配置中心,则 spring.cloud.polaris.address 用于指定注册中心集群的地址,spring.cloud.polaris.config.address 用于指定配置中心的地址。
如下所示:
spring:
application:
name: ${application.name}
cloud:
polaris:
address: grpc://${修改为第一步部署的 Polaris 服务地址}:8091 # 必填
namespace: default # 全局 namespace 参数
config:
address: grpc://${独立的配置中心}:8093 # 选填,只有在配置中心和注册中心是两个不同的地址时才需要配置
auto-refresh: true # 选填,当配置发布后,动态刷新 Spring 上下文,默认值为 true
2. 注入配置文件
我们推荐的最佳实践是在北极星管控端创建一个名为当前应用名( ${spring.application.name}) 的配置分组,Spring Cloud Tencent Config 会自动注入当前应用名分组下的
-
application-${activeProfile}.properties
-
application-${activeProfile}.yml
-
application.properties
-
application.yml
-
bootstrap-${activeProfile}.properties
-
bootstrap-${activeProfile}.yml
-
bootstrap.properties
-
bootstrap.yml
优先级从上到下依次降低
注意:是 yml 后缀,而不是 yaml
自动注入以上配置文件符合 Spring Boot 的规范,能够满足绝大部分应用场景了。只有当您需要注入额外自定义的配置文件时,才需要在 bootstrap.yml 里配置 spring.cloud.polaris.config.groups,如下所示:
spring:
cloud:
polaris:
config:
groups:
- name: ${spring.application.name} # 选填,注入自定义配置的配置分组
files: [ "config/application.properties", "config/bootstrap.yml" ] # 注入自定义配置文件列表,当 key 冲突时,排在前面的配置文件优先级高于后面
第四步:代码里使用配置
1. 通过 @Value 注入
@Value("${wechat.appid}")
public String appid;
@Value("${wechat.secret}")
private String secret;
2. 通过 @ConfigurationProperties 注入
@Component
@ConfigurationProperties(prefix = "teacher")
@RefreshScope //如果使用反射模式,则不需要加这个注解
public class Person {
private String name;
private int age;
String getName() {
return name;
}
void setName(String name) {
this.name = name;
}
int getAge() {
return age;
}
void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User{" + "name='" + name + '\'' + ", age=" + age + '}';
}
}
第五步:在北极星控制台添加配置文件
参考这里 Polaris-配置
第六步:启动应用
到此接入 Spring Cloud Tencent Config 即已完成。
第七步:实现动态刷新配置能力
Spring Cloud Tencent 1.7.0(不包含) 之前的版本通过 Spring Cloud 标准的 @RefreshScope 实现配置动态刷新。@RefreshScope 存在以下局限性:
-
每次刷新配置,需要重新构建整个 Spring Context 重建 Bean,影响面非常大
-
代码里层面需要引入 @RefreshScope 注解
1.7.1 版本(包含)之后,SCT 优化了动态刷新的实现方式。
刷新 @Value 属性
应用启动时扫描所有的 Bean,构建 @Value 属性对应的 Bean 的映射关系。当属性配置更新时,找到所有的待更新的 Bean 并利用 Java 的反射机制更新属性。
刷新 @ConfigurationProperties 配置类
相比于 @RefreshScope 重建所有的 Bean,优化之后的刷新机制只需要重建更新的配置对应的 @ConfigurationProperties Bean,影响面更小。实现原理请看 PolarisRefreshAffectedContextRefresher 和 AffectedConfigurationPropertiesRebinder
如果您想使用传统的 @RefreshScope 方式刷新配置,可以配置 spring.cloud.polaris.config.refresh-type=refresh_context 。
关闭动态刷新能力
在 bootstrap.yml 里配置 spring.cloud.polaris.config.auto-refresh=false
拓展使用
自定义配置监听器
方式一:使用 SCT 的事件回调机制
1.6.0 版本(包含)之后,新增了配置变更回调事件能力。可通过注解@PolarisConfigKVFileChangeListener实现针对指定的配置属性名称或者属性前缀进行监听,配置发生变更时会触发方法回调。
注意:目前只支持 KV 结构的配置文件监听
@Component
public final class PersonConfigChangeListener {
/**
* PolarisConfigKVFileChangeListener Example .
* @param event instance of {@link ConfigChangeEvent}
*/
@PolarisConfigKVFileChangeListener(interestedKeyPrefixes = "teacher")
public void onChange(ConfigChangeEvent event) {
Set<String> changedKeys = event.changedKeys();
for (String changedKey : changedKeys) {
System.out.printf("%s = %s \n", changedKey, event.getChange(changedKey));
}
}
}
方式二:使用 Spring Boot 的事件机制
1.8.0 版本之后,可通过 Spring Boot 标准事件机制来监听配置的变更,代码如下所示:
@Component
public class PersonConfigChangeSpringListener implements ApplicationListener<ConfigChangeSpringEvent> {
@Override
public void onApplicationEvent(ConfigChangeSpringEvent event) {
for (String key : event.changedKeys()) {
System.out.println("Change Key = " + key + ", info = " + event.getChange(key));
}
}
}
支持 Spring Config Data
SCT 2021 及以上版本支持了标准的 Spring Config Data 方式注入配置文件。同样的 SCT 默认会注入 application.yml 、application-${activeProfile}.yml、bootstrap.yml、bootstrap-${activeProfile}.yml,除此之外可以通过以下配置注入额外的配置文件。
spring
config:
import:
- optional:polaris
- optional:polaris:test.yml
- optional:polaris:configdataexample:test.yml
- optional:polaris:config/bootstrap.yml
格式说明
optional:${数据来源,固定值 polaris}:${配置分组名:缺省值为当前应用名}:${配置文件名}
本地开发模式(自1.8.0 版本)
在某些场景下,期望使用本地的配置文件而不是从远端的北极星服务获取配置。例如:
-
当前开发环境处于一个没有网络的环境,飞机上、游轮上等
-
避免修改北极星服务端的配置从而影响其它环境的配置
1.8.0 版本之后,动态配置模块将会在本地 ./polaris/backup/config 目录下缓存从北极星服务端获取的所有配置文件。SCT 配置 spring.cloud.polaris.config.data-source=local 参数即可切换到本地模式(从 ./polaris/backup/config 读取配置)。此时如果您需要修改配置,则只需要修改 ./polaris/backup/config 下的配置文件即可。
注意:修改配置文件时需要同时增加版本号,因为需要通过版本号来做乐观锁,只有在版本号增大时,才认为配置文件有修改
另外,您需要自定义本地文件目录可以通过 spring.cloud.polaris.config.local-file-root-path 配置项指定根目录。
Actuator Endpoint
Spring Cloud Tencent 扩展了 Spring Boot 标准的 Actuator 能力,通过 Actuator 接口,可以实时查询当前运行实例内存里配置文件内容,便于排查问题。详细可以参考:
客户端端视角
-
应用启动时,同步从服务端拉取一次配置,获取最新的配置内容
-
把第一步拉取到的所有的配置文件生成 List<File->Version> 的数据 ,并向服务端发送订阅配置请求,请求内容为 List<File->Version>
-
当收到配置文件的推送消息时,向服务端拉取最新的配置文件
订阅配置服务端视角
-
先检查客户端 List<File->Version> 的请求里是否存在 File 版本号落后,如果存在,则立马响应 File -> NewVersion 内容给客户端
-
如果客户端配置文件版本号都是最新的,则在内存里维护 File -> List<Client> 的数据结构并 Hold 请求 30s。如果 30s 内有配置文件发布,则立马响应请求,返回 File -> NewVersion 给所有客户端
发布推送配置简化流程
-
用户在界面点击发布按钮,服务端更新数据库里配置发布表的数据。配置发布表的核心字段:file, version, content, mtime
-
每个北极星服务端实例,都会定时1s扫描配置发布表,根据 mtime 捞出最近 1s 内变更过的数据
-
北极星服务端实例扫描到最新变更的数据之后
-
重新加载内存缓存
-
向内存里的消息发布管道里写入一条消息
4. 推送协程从消息发布管道里获取到消息,并消费消息。通过 File -> List<Client> 信息,获取所有订阅配置文件的客户端信息,并响应客户端 Hold 的请求。