SpringCloud配置文件刷新之@RefreshScope
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringCloud配置文件刷新之@RefreshScope相关的知识,希望对你有一定的参考价值。
参考技术A 当遇到生产环境配置参数需要调整,但又没有配置中心的支持的情况下,只能重启应用以加载新参数,可能会影响业务系统运行,太暴力不优雅;@RefreshScope注解能帮助我们做局部的参数刷新,但侵入性较强,需要开发阶段提前预知可能的刷新点,并且该注解底层是依赖于cglib进行代理的,所以不要掉入cglib的坑,出现刷了也不更新情况;
常规的操作姿势大致有下面5个步骤;
1、加依赖
2、加yml配置
3、加注解
4、修改参数
修改码云或者git上的配置文件
5、发送刷新请求
Spring Cloud 是如何实现热更新的 http://www.scienjus.com/spring-cloud-refresh/
SpringCloud - Spring Cloud 之 Config分布式配置;加解密;配置信息局部刷新;Spring Cloud Bus+RabbitMQ全局刷新(十六)
阅读本文前可先参考
SpringCloud - Spring Cloud根/父项目,开发准备(二)_MinggeQingchun的博客-CSDN博客
https://blog.csdn.net/MinggeQingchun/article/details/125337347
一、加解密
在Git仓库中明文存储配置信息值,对于某些敏感的配置内容(例如数据库账号、密码等),应该加密存储,config server 对配置内容提供了加密与解密支持
安装JCE
config server的加解密功能依赖Java Cryptography Extension(JCE)
Java 8 JCE下载地址:
JCE Unlimited Strength Jurisdiction Policy Files for JDK/JRE 8 Download
下载得到JCE的zip压缩包并解压,将其中的jar包覆盖到JDK/jre/lib/security目录下;
对称加密
config server提供了加密与解密的接口,分别是
加密接口:http://localhost:8888/encrypt
解密接口:http://localhost:8888/decrypt (这个接口我们不需要用,解密是config-server自动完成的)
1、在原项目 springcloud-8-service-config 中添加bootstrap.properties配置文件,配置密钥
#设置对称密钥,用这个密钥进行加密和解密
encrypt.key=springcloudconfig123456
2、运行项目,验证加解密:(可通过Postman调用)
加密
解密
3、修改 git仓库的配置文件application-dev.properties,将数据库账户、密码修改,上传到Git仓库,运行springcloud-8-service-config查验
注:
加密的字符串前面一定要带 cipher ,不然会是普通字符串,不会被解密,如下
访问 http://localhost:8888/master/application-dev.properties
得到秘钥原文
二、 配置信息局部刷新
实际应用生产中,不免需要修改远端配置文件,不可能重启客户端服务去获得最新的配置。
Spring Boot 的actuator提供了一个刷新端点/refresh,我们可以访问客户端的 /refresh 端点进行刷新;访问该端点需要使用 POST 方式,需要提前引入依赖 actuator
1、在 spring cloud server 服务端项目 springcloud-8-service-config 添加依赖
<!-- spring-boot-starter-actuator
SpringBoot的一个监控actuator提供了一个刷新端点/refresh,我们可以访问客户端的 /refresh 端点进行刷新
-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
2、在spring cloud config 客户端项目 springcloud-8-service-config-consumer 的Controller上添加注解 @RefreshScope 注解,添加这个注解的类会在配置更新时得到处理
RefreshScope是spring cloud提供的一种特殊的scope实现,用来实现配置、实例热加载
@RefreshScope
@RestController
public class GoodsController
//产品服务的接口地址(直连)
// private final String GOODS_SERVICE_URL = "http://localhost:9001/service/goodList";
//产品服务的接口地址 (注册中心服务名)
// private final String GOODS_SERVICE_EUREKA_URL = "http://springcloud-3-service-eureka-provider/eureka/service/goodList";
// @Autowired
// private RestTemplate restTemplate;
//feign的远程调用客户端34-SPRINGCLOUD-SERVICE-GOODS
@Autowired
private ProviderConfigGoodsRemoteClient goodsRemoteClient;
/**
* 读取远程配置中心的配置信息
*/
@Value("$eureka.client.service-url.defaultZone")
private String defaultZone;
/**
* 读取远程配置中心的配置
*/
@GetMapping("/springcloud/getConfig")
public @ResponseBody Object getConfig()
return defaultZone;
@GetMapping(value = "/springcloud/eureka/config/goodList")
public String getGoodList(Model model)
//调用远程的一个controller, restful的调用,通过feign这种声明式的远程调用,goodsRemoteClient就像dubbo里面的接口层一样
List<Goods> goodsList = goodsRemoteClient.goods();
model.addAttribute("goodsList", goodsList);
return "goods";
3、在spring cloud config 客户端项目 springcloud-8-service-config-consumer 的配置文件加上
#配置 spring boot 监控端点的访问权限
#暴露 endpoints,由于endpoints 中会包含很多敏感信息,除了 health 和 info 两个支持直接访问外,其他的默认不能直接访问
management.endpoints.web.exposure.include=*
4、访问http://localhost:8888/actuator/refresh 进行手动刷新配置
三、Spring Cloud Bus + RabbitMQ 全局刷新
使用/actuator/refresh端点手动刷新配置虽然可以实现刷新,但所有微服务节点的配置都需要手动去刷新,如果微服务非常多,其工作量非常庞大
有没有配置“一次通知,处处生效”的的自动刷新方式呢?Spring Cloud Config 配合 Bus 就可以实现配置的动态刷新。
Spring Cloud Bus 又被称为消息总线,它能够通过轻量级的消息代理(例如 RabbitMQ、Kafka 等)将微服务架构中的各个服务连接起来,实现广播状态更改、事件推送等功能,还可以实现微服务之间的通信功能。可以将Spring Cloud Bus想象成一个分布式的Spring Boot Actuator
目前 Spring Cloud Bus 支持两种消息代理:RabbitMQ 和 Kafka。
Spring Cloud Bus 的基本原理
Spring Cloud Bus 会使用一个轻量级的消息代理来构建一个公共的消息主题 Topic(默认为“springCloudBus”),这个 Topic 中的消息会被所有服务实例监听和消费。当其中的一个服务刷新数据时,Spring Cloud Bus 会把信息保存到 Topic 中,这样监听这个 Topic 的服务就收到消息并自动消费。
Spring Cloud Bus 动态刷新配置的原理
当 Git 仓库中的配置发生了改变,我们只需要向某一个服务(既可以是 Config 服务端,也可以是 Config 客户端)发送一个 POST 请求,Spring Cloud Bus 就可以通过消息代理通知其他服务重新拉取最新配置,以实现配置的动态刷新。
Spring Cloud Bus 动态刷新配置的工作原理,如下图所示:
Spring Cloud Bus 实现配置的动态刷新需要以下步骤:
1、当 Git 仓库中的配置发生改变后,运维人员向 Config 服务端发送一个 POST 请求,请求路径为“/actuator/refresh”
2、Config 服务端接收到请求后,会将该请求转发给服务总线 Spring Cloud Bus。
3、Spring Cloud Bus 接到消息后,会通知给所有 Config 客户端。
4、Config 客户端接收到通知,请求 Config 服务端拉取最新配置。
5、所有 Config 客户端都获取到最新的配置
1、Config server服务端
1、springcloud-8-service-config 添加依赖
<!-- spring-cloud-starter-bus-amqp -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
<!-- spring-boot-starter-actuator -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
2、添加 RabbitMQ 配置
#配置rabbitmq
spring.rabbitmq.host=192.168.133.128
spring.rabbitmq.port=5672
spring.rabbitmq.username=root
spring.rabbitmq.password=root
3、开启spring cloud bus,默认是开启的,也可以省略该配置
#开启spring cloud bus,默认是开启的,也可以省略该配置
spring.cloud.bus.enabled=true
4、打开所有的web访问端点
#打开所有的web访问端点
management.endpoints.web.exposure.include=*
2、Config Client客户端配置
1、添加spring-cloud-starter-bus-amqp 依赖(其他各个微服务用于接收消息,那么也需要有spring cloud bus的依赖和RabbitMQ的连接信息)
<!-- spring-cloud-starter-bus-amqp -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
2、 配置RabbitMQ
#配置rabbitmq
spring.rabbitmq.host=192.168.133.128
spring.rabbitmq.port=5672
spring.rabbitmq.username=root
spring.rabbitmq.password=root
3、启动 springcloud-8-service-config,post方式请求地址:http://localhost:8888/actuator/bus-refresh
如果返回成功,则RabbitMQ将收到消息,然后微服务会消费消息,config的所有客户端的微服务配置都会动态刷新
以上是关于SpringCloud配置文件刷新之@RefreshScope的主要内容,如果未能解决你的问题,请参考以下文章
SrpingCloud 之SrpingCloud config分布式配置中心实时刷新
SpringCloud - Spring Cloud 之 Config分布式配置;加解密;配置信息局部刷新;Spring Cloud Bus+RabbitMQ全局刷新(十六)