SpringCloud Config不一样的配置更新姿势

背景

当我们更新了ConfigServer中的相关配置(本文讲的是基于MySQL的配置存储),想要在不关闭重启服务的情况下,对配置进行更新,这时就需要用到Spring提供的配置刷新功能。

配置刷新的原理都是通过调用各个服务的 /actuator/refresh 接口,从而触发重新拉取ConfigServer配置。

配置更新的各种姿势

1. 手动调用各个服务的 /actuator/refresh 接口

首先需要确保该端点处理开启状态

management:
  endpoints:
    web:
      exposure:
        include: health,info,refresh # 加入refresh开启端口

在需要刷新的配置上,加上@RefreshScope注解,如下是一个token过期时间的配置:

@Component
@Data
@RefreshScope
public class TokenProperties {
    @Value("${token.expire-time}")
    private Integer tokenExpireTime;
}

手动调用 localhost:8080/actuator/refresh

缺点,SpringCloud会有很多服务,而且一个服务会有多个节点,需要手动执行多次。

2. 使用Spring Cloud Bus消息总线触发配置刷新

Spring Cloud Bus会向外提供一个http接口,即图中的/bus/refresh。我们将这个接口配置到远程的git的webhook上,当git上的文件内容发生变动时,就会自动调用/bus-refresh接口。Bus就会通知config-server,config-server会发布更新消息到消息总线的消息队列中,其他服务订阅到该消息就会信息刷新,从而实现整个微服务进行自动刷新。

SpringCloudBus配置刷新原理

了解下其刷新原理,本文不做展开,具体细节可参考文章(上面的图也是来自这位博主) https://www.cnblogs.com/babycomeon/p/11141160.html

优点,配置刷新变可触发重新拉取配置,无需手动调用

3. 自定义刷新接口(集成actuator/refresh)

为什么不使用SpringCloudBus?
答:当我们一次性修改某个服务的多项配置,或者你并不想这个配置马上去刷新,而是等待某个时间点你在去一次性刷新该服务配置,这时候自定义刷新配置更符合你的需求。

其实原理就是将第一种方式(actuator/refresh调用)进行封装,通过服务发现获取到该服务的多个实例,依次去调用各个实例的 actuator/refresh接口。

对外提供一个接口刷新配置,关键代码如下:

@RestController
@Slf4j
public class ConfigRefreshController {

    @Resource
    private DiscoveryClient discoveryClient;

    @GetMapping("/api/config/refresh")
    public String refresh (@Valid @NotEmpty String serviceName, ServerHttpResponse serverHttpResponse) {
        // 获取改服务的实例列表
        List serviceInstances = discoveryClient.getInstances(serviceName);
        List resultList = new ArrayList<>(serviceInstances.size());
        // 依次调用实例的刷新方法
        serviceInstances.forEach(serviceInstance -> {
            ConfigRefreshResult configRefreshResult = new ConfigRefreshResult();
            configRefreshResult.setServiceName(serviceName);
            configRefreshResult.setUrl(serviceInstance.getUri().toString());
            try {
                String result = HttpUtil.httpPost(serviceInstance.getUri() + "/actuator/refresh", null);
                configRefreshResult.setResult(result);
            } catch (Exception e) {
                log.error(JSON.toJSONString(serviceInstance));
                e.printStackTrace();
                configRefreshResult.setResult(e.getMessage());
            }
            resultList.add(configRefreshResult);
        });
        serverHttpResponse.setStatusCode(HttpStatus.OK);
        serverHttpResponse.getHeaders().setContentType(MediaType.APPLICATION_JSON);
        return JSON.toJSONString(resultList);
    }
}

你可能感兴趣的:(SpringCloud Config不一样的配置更新姿势)