分布式配置

最近更新时间:2019-10-30 09:45:27

准备工作

开始实践分布式配置功能前,请确保已完成了 SDK 下载
使用分布式配置功能涉及到以下部分:

  • pom.xml 添加配置依赖项
  • 在代码中引用配置
  • 轻量级服务注册中心下发动态配置
  • 通过 TSF 平台下发动态配置

一、依赖项

添加 pom.xml 依赖:

<dependency>
  <groupId>com.tencent.tsf</groupId>
  <artifactId>spring-cloud-tsf-consul-config</artifactId>
  <version><!-- 调整为 SDK 最新版本号 --></version>
</dependency>
 <!-- 1.12.0之前(不包含1.12.0)版本 SDK,使用分布式配置自动刷新功能时,要添加 actuator 的依赖包
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
-->

二、代码引用配置

用户可通过两种方式更新代码中的配置信息:使用配置类@ConfigurationProperties@Value注解。@Value比较适用于配置比较少的场景,而@ConfigurationProperties则更适用于有较多配置的情况。
用户也可以动态更新应用配置文件(如 application.yml)中的配置,如动态更改 redis 的地址或者鉴权功能开关等。

使用配置类 @ConfigurationProperties

provider-demo的 ProviderNameConfig 类中,有一个字符串类型的变量name。其中:

  • 使用@ConfigurationProperties注解来标明这个类是一个配置类。
  • 使用@RefreshScope注解开启 refresh 机制。
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;

@Component
@RefreshScope
@ConfigurationProperties(prefix="provider.config")
public class ProviderNameConfig {
    private String name = "echo-provider-default-name";

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

使用 @Value 注解

在启动类ProviderApplication中,使用@Value注解来标识一个配置变量。下面的示例中${test.demo.prop:default}test.demo.prop是在动态配置下发中使用的 key,value 默认是default

// 其他 import 
import org.springframework.web.bind.annotation.RestController;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;

public class ProviderApplication {
    public static void main(String[] args) {
        SpringApplication.run(ProviderApplication.class, args);
    }    

    @Value("${test.demo.prop:defalut}")
    private String propFromValue;

    @RequestMapping("/hello/") public String index() {
        String result = "propFromValue: " + propFromValue + "\n";
        return result;
    }                
}

配置更新触发回调

配置更新触发回调功能允许程序在不重启的情况下动态修改业务逻辑。当配置更新时,触发配置回调方法的调用。配置更新触发回调功能的使用场景包括:

  • 程序使用一个防刷开关配置,当开关为启用状态时,启动防刷逻辑,当开关为关闭状态时,停用防刷逻辑。
  • 程序使用一个ReidsConfig的动态配置类,包含 redis 的 host 和 port,当更新这个配置时,更新 Redis 实例。
  • 配置更新后发出通知消息,通知本地或者远程的其他模块执行变更逻辑

TSF 分布式配置支持使用@ConfigChangeListener注解且实现ConfigChangeCallback接口。在SimpleConfigurationListener类中,设置callback回调方法。支持场景包括:

  • 支持按照配置项前缀模糊匹配方式。
  • 支持配置项精确匹配方式。
  • 支持回调方法同步 sync 或者异步 async 方式执行。
// prefix: 配置信息前缀,前缀匹配
// async: 回调事件是否异步执行,默认 false
// value: 精确匹配配置项
// 监听前缀为 io 的配置项变更
@ConfigChangeListener(prefix = "io",async = true)
public class SimpleConfigurationListener implements ConfigChangeCallback {
    @Autowired
    private SimpleService simpleService;
    @Override
    public void callback(ConfigProperty lastConfigItem, ConfigProperty currentConfigItem) {
        simpleService.saySomething("receive Consul Config Change Event >>>> ");
        simpleService.saySomething("Last config: [" + currentConfigItem.getKey()  + ":" +lastConfigItem.getValue() + "]");
        simpleService.saySomething("Current config: [" + currentConfigItem.getKey()  + ":" +currentConfigItem.getValue() + "]");
    }
}
@Component
public class SimpleService {
    public void saySomething(String words){
        System.out.println(words);
    }
}

三、轻量级服务注册中心下发动态配置

前提条件

  1. 已完成轻量级服务注册中心的安装和启动(参考 轻量级服务注册中心)。
  2. 服务已连接到轻量级服务注册中心。

用户可以使用轻量级服务注册中心下发动态配置,下面以 provider-demo 为例说明更新的具体步骤:

  1. 浏览器访问 consul 控制台(http://127.0.0.1:8500)。
    说明:

    只有成功启动了 consul 后,才能访问 consul 控制台。

  2. 单击菜单栏【Key/Value】。
  3. 单击【Create】,在配置新建界面填写 key 和 value。
    • key 是 /config/application/data 或 /config/application/{spring.profiles.active}/data
    • value 是配置的内容,截图中使用 provider-demo 中的自定义配置 provider.config.name=testname123。
  4. 单击【Save】,观察 stdout 中是否出现[TSF SDK] Configuration Change Listener: key: {}, old value: null, new value: testname123,如果出现说明配置生效。

四、通过 TSF 平台下发动态配置

用户可以通过 TSF 平台来下发动态配置,前提条件:

  • 已经在 TSF 平台上部署了provider-democonsumer-demo应用。
  • 部署 provider-demo 的部署组的日志配置项的日志路径中包含了/tsf-demo-logs/provider-demo/root.log,以确保打印的日志被采集后,可以通过控制台查看应用的日志。

关于如何通过控制台创建及下发更新的配置,请参考 应用配置

如果希望修改ProviderNameConfig类中的providerName的值,创建配置时,配置内容填写:

provider:
  config:
    name: testname123

将配置发布到已部署provider-demo的部署组上,检查打印的日志中是否 name 的值已更新。如果已更新,说明更新的配置生效。

provider-demo -- provider config name: testname123