Nacos通过RefreshScope实现配置自动更新的方式分享

 更新时间:2023年09月26日 08:43:44   作者:zooooooooy  
这篇文章主要给大家介绍了Nacos如何通过RefreshScope实现配置自动更新,文中给了两种实现方式供大家参考,对大家的学习或工作有一定的帮助,需要的朋友可以参考下

实现方式

有两种方式,使用 @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中可能变量设置方式可能非常多,导致不能准确定位到变量对应的配置类,所以每次都是刷新所有的配置类和注解类,开销也很大。

以上就是详解Nacos如何通过RefreshScope实现配置自动更新的详细内容,更多关于Nacos RefreshScope自动更新的资料请关注脚本之家其它相关文章!

相关文章

  • Java 关系运算符详情及案例(下)

    Java 关系运算符详情及案例(下)

    这篇文章主要介绍了Java 关系运算符详情及案例的实现,主要续上篇文章,上一篇文章我们讲到“等于”运算符 (==)、“不等于”运算符(!=)、“大于”运算符(>) ,这篇文章继续给大家讲解相关知识,需要的朋友可以参考一下
    2021-12-12
  • Java多线程之死锁详解

    Java多线程之死锁详解

    这篇文章主要介绍了Java多线程的死锁,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-10-10
  • java垃圾回收原理之GC算法基础

    java垃圾回收原理之GC算法基础

    本章简要介绍GC的基本原理和相关技术, 下一章节再详细讲解GC算法的具体实现。各种垃圾收集器的实现细节虽然并不相同,但总体而言,垃圾收集器都专注于两件事情:查找所有存活对象,抛弃其他的部分,即死对象,不再使用的对象
    2022-01-01
  • Java棋类游戏实践之单机版五子棋

    Java棋类游戏实践之单机版五子棋

    这篇文章主要为大家详细介绍了Java棋类游戏中的五子棋实现方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-02-02
  • Java圆柱体表面积和体积计算代码实例

    Java圆柱体表面积和体积计算代码实例

    这篇文章主要介绍了Java圆柱体表面积和体积计算代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-06-06
  • Java中ArrayBlockingQueue和LinkedBlockingQueue

    Java中ArrayBlockingQueue和LinkedBlockingQueue

    这篇文章主要介绍了Java中ArrayBlockingQueue和LinkedBlockingQueue,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的朋友可以参考一下
    2022-09-09
  • Java实现软件运行时启动信息窗口的方法

    Java实现软件运行时启动信息窗口的方法

    这篇文章主要介绍了Java实现软件运行时启动信息窗口的方法,比较实用的功能,需要的朋友可以参考下
    2014-08-08
  • SpringBoot整合neo4j使用详解

    SpringBoot整合neo4j使用详解

    这篇文章将和大家详细聊聊如何在springboot应用中集成和使用neo4j,文中有详细的实现流程和实例代码,具有一定的借鉴价值,感兴趣的小伙伴可以跟随小编一起学习一下
    2023-10-10
  • Java项目实现模拟ATM机

    Java项目实现模拟ATM机

    这篇文章主要为大家详细介绍了Java项目实现模拟ATM机,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-05-05
  • 带你用Java全面剖析类和对象

    带你用Java全面剖析类和对象

    下面小编就为大家带来一篇全面理解Java类和对象。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2021-09-09

最新评论