Nacos如何通过RefreshScope实现配置自动更新

本文主要是了解Nacos中配置更新后,如何实现配置项自动更新。

实现方式

有两种方式,使用@ConfigurationProperties注解调用get请求或者@RefreshScope + @Value这两种来实现配置的刷新。

配置属性

现象

初始值是false,修改Nacos中的配置文件为true。很快配置项就变了。

idea日志

可以看到是触发了配置的更新并打印了配置变化项。

DEBUG

通过Debug知道大体流程如下:

配置更新的大体流程如上。NacosClient中使用了一个线程池的无线循环来监测配置的变更,即长轮询的方式去Nacos Server中去获取配置变更。

自动刷新

从上面我们可以得到配置已经更新到了Environment中,但是持有配置项的类由于已经初始化是不会变更已经设置进去的属性。容器工厂通过销毁bean,重建bean的方式来重新初始化配置对象,达到整个配置更新的操作。

配置刷新(@ConfigurationProperties)

refreshEnvironment(刷新环境变量)

刷新环境变量同时通过对比找出变更的配置项,再触发环境改变Event事件。

ConfigurationPropertiesRebinder(配置重新绑定)

配置重新绑定类同步也实现ApplicationListener接口,监听了EnvironmentChangeEvent的改变。是通过beanFactory来销毁bean和初始化bean。

疑问?

由于Spring框架的限制,当刷新配置项时,所有的配置项都会刷新,走bean的销毁和创建过程。往往我们只需要更新其中变化的配置项即可。

已经得到了变更的配置项了,结果还是刷新了所有的配置项。如果不需要进行刷新,也可以添加自定义的配置项,把对应的配置加进来即可。

默认是hikari数据库连接池的datasource对象。防止刷新时造成数据库连接池重新销毁创建,造成连接的浪费。


其实我们可以通过keys想办法定位对应的配置项,在Environment中附加每一个属性对应的来源。这样可以直接通过变量操作来源进行对应的配置刷新。如果想粒度更小的话,在初始化过程中反射设置属性时,可以只设置变更的属性,最小的代价变更配置类的变量值。

单例,通过反射的方式设置配置变更项。可以通过get方式来获取变量后的值。

变量刷新(@RefreshScope + @Value)

非配置类上配置了@RefreshScope注解后,在abstractApplicationContext中实例化bean时没有走单例或者原型的初始化方式。是通过Scope的方式自定义bean的获取方式。

Scope内部会维护一个数组缓存刷新对象。每次获取时从缓存内部获取对象,如果不存在则重新创建,就会重新走一遍对象的实例化,因此Value对象就会重新被赋值。

缓存清除

依据配置,同理可以知道也是通过event机制获取到配置更新,进而去清除缓存。我们debug一下调用栈看一下。

最后其实就是调用了cache的clear方法,清除了所有缓存。再次获取bean时,缓存中不存在,就会重新进行创建。

疑问?

这里也是清除所有缓存,所有@RefreshScope类都会重新创建。虽然对应的配置也会更新,但是也会触发postConstruct,destory等方法,导致出现一些无法预料的问题。应用自动刷新同时也要考虑上述的情况,尽量进行规避。

总结

个人建议走配置更新的方式。通过每次使用get方法来获取到最新的变量即可。配置类没有被重新创建,开销更小,框架也是自动已经集成好了。SpringBoot中可能变量设置方式可能非常多,导致不能准确定位到变量对应的配置类,所以每次都是刷新所有的配置类和注解类,开销也很大。

相关推荐
sg_knight19 小时前
Spring Cloud 2024.x智能运维:AI驱动的故障预测与自愈
java·运维·人工智能·spring boot·spring cloud
拄杖忙学轻声码1 天前
shardingsphere-jdbc集成Seata分布式事务
mysql·spring cloud
码代码的小农1 天前
SpringCloud Alibaba微服务工程搭建
spring·spring cloud·微服务
小杜-coding2 天前
黑马头条day02
java·spring boot·spring·spring cloud·java-ee·maven·mybatis
AronTing2 天前
11-Spring Cloud OpenFeign 深度解析:从基础概念到对比实战
后端·spring cloud·架构
2401_890665862 天前
免费送源码:Java+ssm+MySQL 基于PHP在线考试系统的设计与实现 计算机毕业设计原创定制
java·hadoop·spring boot·python·mysql·spring cloud·php
小杨4043 天前
springboot框架项目实践应用十九(nacos配置中心)
spring boot·后端·spring cloud
Neo Yang3 天前
Spring Cloud初探之使用load balance包做负载均衡(三)
spring cloud·负载均衡·load balance
魔道不误砍柴功3 天前
SpringCloud Alibaba 之分布式全局事务 Seata 原理分析
分布式·spring·spring cloud
Charlie__ZS3 天前
Spring Cloud-负载均衡
spring·spring cloud·负载均衡