2025年nacos配置中心(Nacos配置中心配置变更,客户端自动刷新吗)

nacos配置中心(Nacos配置中心配置变更,客户端自动刷新吗)nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp 目录 nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp 配置中心是 SpringCloud 系统中常见的一种技术方案 配置中心区别于传统的各个系统当中分散的配置方式 它对系统中的配置文件进行集中式 统一管理 使用配置中心好处有 通过配置中心 可以使得配置标准化 格式统一化 当配置信息发生变动时 修改实时生效 无需要重新重启服务器 可以实时去调整相关对应的业务 最近在做技术调研形成落地方案的时候 突然想到了 nacos 的动态配置刷新



        目录      

              

        

        


配置中心是SpringCloud系统中常见的一种技术方案,配置中心区别于传统的各个系统当中分散的配置方式,它对系统中的配置文件进行集中式、统一管理。

使用配置中心好处有:
①、通过配置中心,可以使得配置标准化、格式统一化。

②、当配置信息发生变动时,修改实时生效,无需要重新重启服务器,可以实时去调整相关对应的业务。

最近在做技术调研形成落地方案的时候,突然想到了nacos的动态配置刷新,于是想去看下nacos动态配置到底怎么实现的,今天抽出点时间看了下nacos配置中心源码实现。

所以,本篇文章就介绍nacos是怎么扩展spring实现自己的配置数据动态加载的。

首先第一点需要知道的是nacos动态配置从nacos角度来看核心是通过长轮询(LongPolling)来实现的,我们不妨先从nacos角度来看其长轮询实现方式,然后再看和spring的整合。

所谓长轮询,就是服务器接收到请求后,hold连接一段时间暂时不返回消息,直到进行相关处理完毕后才返回响应信息并关闭连接,客户端接收到响应信息后,进行相关处理,处理完毕后再向服务器发送新的请求。

所以在一次nacos客户端连接服务端当中,服务端断开连接也就有了两种情况:

①、服务端数据发生了变化,需要推送到客户端,向客户端推送数据,断开连接。

②、在一段时间内没有数据发生改变,超时断开连接。

下面我们来看nacos是怎么实现LongPolling的。
nacos长轮询逻辑是在类ClientWorker当中。

这里我们先从类ClientWorker的构造方法看起,因为下面讲的和spring集成部分都是在类ClientWorker的构造方法的上层部分,等说到和spring继承的时候我们再衔接到类ClientWorker的构造方法这个地方。

其实就是拿到项目中配置的nacos服务端地址拼接上uri后直接和nacos服务端进行通信,获取已经发生改变的key。
然后下面整个一个for循环就是对changedGroupKeys进行遍历,从遍历出来的每一项groupKey解析出来dataId、group、tenant,然后通过这三个参数执行getServerConfig()方法获取到真正改变的内容,更新到本地缓存cacheMap中的CacheData。

然后接下来的for循环核心执行的就是通知监听器刷新nacos数据。

我们直接看cacheData.checkListenerMd5()方法的执行逻辑。

遍历所有的监听器,最终执行safeNotifyListener()这个方法很显然这个方法中创建了一个Runnable任务,最终通过监听器Listener里面的线程池或者直接执行这个Runnable任务。

所以,我们接下来重点看Runnable任务执行的逻辑。

这个Runnable任务里面核心逻辑是这行代码。

表示接收到动态修改的内容。
所以我们直接看这行代码的逻辑。
要看这行代码的逻辑,首先需要搞懂这个listener是哪个实现类,在这里先告诉大家,这个实现类是在NacosContextRefresher里面注册nacos监听器的时候创建的内部类,如果自己debug一下也能找到。

NacosContextRefresher这个类其实已经是和spring整合的桥梁了,接下来我们直接看NacosContextRefresher里面注册nacos监听器的时候创建的内部类,我们先看是怎么实现动态刷新数据的,等会再看和spring整合。
这个内部类innerReceive()方法正是实现了AbstractSharedListener这个抽象类,而AbstractSharedListener这个抽象类的顶层接口就是Listener,我们看这个内部类中的核心逻辑有两处:

①、nacosRefreshHistory通过链表的方式记录nacos数据变更历史

②、通过ApplicationContext.publishEvent()方法刷新容器

很显然,我们想看的逻辑正是刷新容器这行代码。

ApplicationContext.publishEvent()方法刷新容器的这行代码我跟着源码跟踪的很深、很久,但是我陷入了疑惑,随着我不断的跟踪spring的源码,发现这行代码的底层是spring的时间发布机制在不重启spring容器的前提下,动态的刷新容器,但是好像和nacos动态刷新加载最新的刚才传过来的数据String configInfo没有关系,也就是说,我想着从nacos服务端拿过来的数据并没有加载到spring中啊。
在这里疑惑了很久,因为跟踪源码并没有发现数据并没有加载到spring中,只是看到了在不重启spring容器的前提下,动态的刷新spring容器,所以这个时候我就猜想,动态的刷新spring容器怎么才能拿到nacos最新的数据呢,突然一个灵感,spring容器重启的时候不就是会初始化第一次从nacos拿最新的数据嘛,后续才通过nacos长轮询获取数据。

然后我在NacosConfigManager这个类的构造方法打了个debug断点,因为这个类就是spring容器启动的时候第一次初始化创建nacos需要的一些组件、开启定时任务等核心逻辑。

果然,是进到了这个debug,也就印证了我的猜想。

上面我们主要是从nacos长轮询LongPolling的核心逻辑倒推监听器怎么执行最后到和spring整合的地方,这里我们详细看下和spring整合的部分。
和spring整合首先看类NacosConfigAutoConfiguration、NacosConfigBootstrapConfiguration这两个配置类,这两个配置类主要创建了nacos的一些核心组件。
重点看类NacosConfigManager和NacosContextRefresher。

NacosConfigManager是创建nacos长轮询的定时任务,定时执行长轮询的定时任务,是nacos配置更新的启动点。

NacosContextRefresher是和spring整合的桥梁,实现了ApplicationContextAware用来获取ApplicationContext,实现了ApplicationListener用来通知spring发布时间通知。

在发布事件通知的逻辑中就注册了nacos的监听器。

nacos注册的监听器的这个内部类正是我们刚才看的动态刷新数据通知spring发布事件通知的那个内部类。
通过这两个类就实现了spring容器启动的时候启动nacos长轮询监听服务端数据变更和监听到数据变更后动态获取最新的nacos配置数据。


编程小号
上一篇 2026-03-09 07:06
下一篇 2026-03-09 07:51

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/bian-cheng-ri-ji/51744.html