【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
上一篇: 微信小程序图片横向左右滑动案例
下一篇: 本地连接mongoDB失败,Error: couldn't connect to server 127.0.0.1:27017, connection atte
推荐阅读
-
使用Spring Cloud Bus自动动态刷新配置文件的流程总结
-
使用Spring Cloud Config搭建配置中心(实现自动刷新)
-
spring cloud config+bus实现配置中心的自动刷新
-
Spring Cloud Bus与RabbitMq实现config-server自动刷新配置及注意问题
-
Spring Cloud(6)消息总线 Spring Cloud Bus + Spring Cloud Config 实现全自动刷新集群配置
-
SpringCloud-Spring Cloud Config配置属性刷新之手动刷新
-
【Spring Cloud总结】39.Spring Cloud Config配置属性刷新之手动刷新
-
Spring Cloud【Finchley】实战-06使用/actuator/bus-refresh端点手动刷新配置 + 使用Spring Cloud Bus自动更新配置
-
Spring Cloud 进阶之路 -- 消息总线 Spring Cloud Bus 配置手动刷新和动态自动刷新
-
SpringCloud-Spring Cloud Config配置属性刷新之自动刷新