【Spring Cloud总结】39.Spring Cloud Config配置属性刷新之手动刷新

接上篇《38.Spring Cloud Config 与Eureka配合使用》  Spring Cloud版本为Finchley.SR2版

上两篇我们讲解了有关Spring Cloud Config与Eureka的配合使用,本篇我们来讲解Spring Cloud Config是如何来刷新其配置属性的。

本部分官方文档:https://cloud.spring.io/spring-cloud-static/Finchley.SR4/single/spring-cloud.html#refresh-scope
注:好像Finchley.SR2的文档已经挂了,最新的是Finchley.SR4的文档。

一、动态刷新属性的需求

Spring Cloud Config的配置刷新是指其配置属性的刷新。例如之前我们Config Client中获取profile属性的代码:

package com.microserver.cloud;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ConfigClientController {
    
    @Value("${type}")
    private String profileType;
    
    @GetMapping("/profileType")
    private String getProfileType() {
        return this.profileType;
    }
} 

这里我们配置文件中spring.cloud.config.profile配置的是dev,而Config Client的应用名(spring.application.name)为microserver-config-client,所以在远端的gitee仓库中,会获取到名为“microserver-config-client-dev.yml”文件中的type属性的值“client-dev”。

如果我们有一天把gitee仓库中的“icroserver-config-client-dev.yml”文件中的type属性改为了其他值,但是我的系统目前运行在生产环境下,想要在不停机的情况下,刷新上面的profileType属性,使其获取新的type值,应该怎么做呢?

注:这种场景很常见,例如大型互联网公司的电商网站,在双十一或者其他购物高峰期的时候,访问量很大,此时我们有可能需要调整数据库连接池或一些其它配置(流控、连接池大小等)的性能参数,使其能够适应更高的访问量,此时我们也是不愿意重新服务来达到这个效果的。

二、实现配置刷新的手动刷新

1、具体实现
Spring Cloud Config是支持配置刷新的,我们下面来实现一个手动刷新属性的效果。
实现自动刷新效果,不需要修改Config Server的代码,只需要修改Config Client即可。
复制之前的microserver-config-client工程,更名为“microserver-config-client-refresh”:

然后我们修改ConfigClientController类:

package com.microserver.cloud;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ConfigClientController {
    
    @Autowired 
    private Paramters paramters;
    
    @GetMapping("/profileType")
    private String getProfileType() {
        return paramters.getProfileType();
    }
} 

我们将profileType封装在了一个Paramters类中:

package com.microserver.cloud;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;

@Component
@RefreshScope
public class Paramters {
    @Value("${type}")
    private String profileType;

    public String getProfileType() {
        return profileType;
    }

    public void setProfileType(String profileType) {
        this.profileType = profileType;
    }
    
}

这里我们在Paramters类结构的上方新增了一个名为“@RefreshScope”的注解,该注解的作用我们测试完毕之后会详细讲解。
然后在pom.xml文件中添加actuator的依赖:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <artifactId>microserver-config-client-refresh</artifactId>
  <name>microserver-config-client-refresh</name>
  
  <parent>
        <groupId>com.microserver.cloud</groupId>
        <artifactId>microserver-spring-cloud</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
  
  <dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-config-client</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-actuator</artifactId>
    </dependency>
</dependencies>
  
</project>

对于actuator依赖大家肯定不陌生,它是可以帮助我们监控和管理Spring Boot应用的服务组件,提供健康检查、审计、统计和HTTP追踪等功能。

为什么要加actuator依赖呢?这里我们也留一个悬念。

然后更新application.yml文件,添加暴露refresh端点的配置:

server:
  port: 8091
spring:
  application:
    name: microserver-config-client
management:
  endpoints:
    web:
      exposure:
        include: refresh
    
type: abcd

注:在Spring Boot升级到2.0.3.RELEASE后需新增配置,之前不需要配置。

我们启动原来的microserver-config-server配置服务,和新写的microserver-config-client-refresh服务(先启动服务端,在启动客户端,否则参数获取不到):

然后访问microserver-config-client-refresh服务的“profileType”节点,可以看到当前获取的还是之前的“client-dev”值:

此时我们在本地仓库,将“microserver-config-client-dev.yml”文件中的type属性修改为“client-dev-refresh”,并提交远程仓库:

然后此时就是手工刷新的重点了,我们打开postman工具,访问microserver-config-client-refresh服务的一个“refresh”服务,即“http://localhost:8091/actuator/refresh”:

可以看到返回的结果:

[
    "config.client.version",
    "type"
]

这里就是更新的相关的远程配置的名称。

我们看一下客户端控制台打印的日志:

可以看到客户端重新访问了Config Server的服务,重新进行了Fetching config动作,将相关的参数加载进来。

然后我们重新访问服务的“profileType”节点,可以看到当前获取的是修改后的“client-dev-refresh”值:

2、一些异常问题的解决
在上面的操作过程中,如果童鞋们不将profileType封装到Paramters类中,依然使用“return this.profileType”的方式获取profileType值,可能会遇到访问microserver-config-client-refresh服务的“profileType”节点,发现访问不到值的情况,而一旦拿掉@RefreshScope就可以获取到,这是怎么回事?为什么加了@RefreshScope注解后获取不到Value的值了呢?

我们目前使用的springboot和springcloud版本分别如下:
springboot 2.0.4
springcloud  Finchley.SR2

这极有可能是以上两个版本组合之后出现的一个Bug,这个版本中,将@RefreshScope放到controller层,任何在controller层注入的bean取值都为null,拿不到任何数据,也不报错。
目前查阅很多资料没有解决方案,只是参考了另一个博主的方法,按照解决方案1的做法实现了数据加载。
下面将两种解决方案提供给大家:
解决方案1:https://blog.csdn.net/soulsda/article/details/89642241
解决方案2:https://www.cnblogs.com/xiaoyao-001/p/11511595.html


三、手工刷新配置的原理

上面我们做了两点来实现手工刷新,一个是为注入配置参数的类添加了@RefreshScope注解,一个是添加了actuator的依赖,那么这两个操作对于手工刷新配置有什么作用呢?

1、@RefreshScope注解
首先我们来说一下@RefreshScope注解。我们在Java中创建的Bean,其中绑定了外部配置的参数,仅在首次访问时初始化。如果一个Bean添加了@RefreshScope注解,这个Bean中的参数就会进行强制懒加载。

而其原理就是,这个注解会给范围内的每个bean创建个代理对象,如果刷新bean,则下次访问bean时(即执行方法)将创建一个新实例。所有生命周期方法都应用于bean实例,因此在刷新时会调用在bean工厂的销毁回调方法,然后在创建新实例时正常调用初始化回调。从原始bean定义创建新的bean实例,因此在创建时会重新加载所有外部配置属性(属性占位符或字符串文字中的表达式)。

所以我们刷新了ConfigClientController类,此时会创建该bean的新的实例,并重新加载所有外部配置属性,我们的profileType参数绑定的“${type}”也会被重新加载,并绑定到profileType参数上。

2、actuator依赖
为什么要添加actuator依赖的依赖呢?我们中间使用了一个“refresh”的刷新服务,而这个刷新服务是由actuator组件提供的,该服务的作用就是用来重新加载bootstrap context以及刷新@RefreshScope注解标注的Bean。

四、手工刷新的弊端

我们是通过访问“refresh”的刷新服务去手工刷新配置的,如果我们的微服务的体量比较大,例如有几百个集群,每个集群有几十个端点需要刷新,我们需要给每个端点都需要用这种post的请求去刷新该端点,这种效率很低,而且时效性不高,在我们需要集体刷新配置时,是有问题的。所以这种情况下我们需要自动刷新的策略来解决此问题。

下一篇我们就来讲解如何对Spring Cloud Config进行自动刷新的操作。

参考:《51CTO学院Spring Cloud高级视频》
https://blog.csdn.net/haveqing/article/details/91414012

转载请注明出处:https://blog.csdn.net/acmman/article/details/106157061

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

光仔December

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值