nacos 配置动态刷新_【Nacos】nacos @NacosValue 动态配置刷新 源码解析

本文深入探讨了Nacos配置动态刷新的工作原理,包括其采用的长轮训机制,详细阐述了配置变更时如何通过客户端和服务端的交互实现配置的实时更新。通过分析源码,揭示了从系统启动、监听器注册、Bean配置到长轮询监听变更的整个过程,以及如何利用反射机制动态刷新Bean的配置值。
摘要由CSDN通过智能技术生成

1 原理思想

Nacos 采用的是 Pull 模式,但并不是简单的 Pull,而是一种长轮训机制,它结合 Push 和 Pull 两者的优势(nacos并没有push)。客户端采用长轮训的方式定时发起 Pull 请求,去检查服务端配置信息是否发生了变更,如果发生了变更,则客户端会根据变更的数据获得最新的配置。所谓的长轮训,是客户端发起轮训请求之后,服务端如果有配置发生变更,就直接返回。

如果客户端发起 Pull 请求后,发现服务端的配置和客户端的配置是保持一致的,那么服务端会先 “Hold” 住这个请求,也就是服务端拿到这个连接之后在指定的时间段内一直不返回结果,直到这段时间内配置发生变化,服务端会把原来 “Hold” 住的请求进行返回。Nacos 服务端收到请求之后,先检查配置是否发生了变更,如果没有,则设置一个定时任务,延期 29.5s 执行,并且把当前的客户端长轮训加入 allSubs 队列。这个时候有两种方式触发该链接结果的返回:// 后面单独看config server的源码解析

第一种是在等待 29.5s 后触发自动检查机制,这个时候不管配置有没有发生变化,都会把结果返回客户端。而 29.5s 就是这个长连接保持的时间。

第二种是在 29.5s 内任意一个时刻,通过 Nacos Dashboard 或者 API 的方式对配置进行了修改,这会触发一个事件机制,监听该事件的任务会遍历 allSubs 队列,找到发生变更的配置项对应的 ClientLongPolling 任务,将变更的数据通过该任务的连接进行返回,就完成一次 “推送” 操作。

这样既能够保证客户端实时感知配置的变化,也降低了服务端的压力。其中,这个长连接的回话超时时间默认是 30s。

2 实现:当远程文件发生变更后【 长轮询】

--->com.alibaba.nacos.client.config.impl.ClientWorker.LongPollingRunnable  实现

3 源码分析

3.1系统启动 注册listener

通过:初始化---->使用默认的publisher;

springboot 是配置的天堂所以一定有个ConfigAutoConfiguration+ConfigBeanDefinitionRegistrar的组合

--->org.springframework.context.support.AbstractApplicationContext#invokeBeanFactoryPostProcessors // bean定义

--->org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanDefinitionRegistryPostProcessors // bean定义

--->org.springframework.context.annotation.ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry //bean定义

--->org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader#loadBeanDefinitionsFromRegistrars // 启动类注解入口

--->com.alibaba.nacos.spring.context.annotation.config.NacosConfigBeanDefinitionRegistrar#registerBeanDefinitions

----// 配置 来源com/alibaba/boot/nacos-config-spring-boot-autoconfigure/0.2.7/nacos-config-spring-boot-autoconfigure-0.2.7.jar!/META-INF/spring.factories

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.alibaba.boot.nacos.config.autoconfigure.NacosConfigAutoConfiguration

[com.alibaba.boot.nacos.config.autoconfigure.NacosConfigAutoConfiguration]

--->import

[com.alibaba.nacos.spring.context.annotation.config.NacosConfigBeanDefinitionRegistrar]

--->com.alibaba.nacos.spring.util.NacosBeanUtils#invokeNacosPropertySourcePostProcessor

--->com.alibaba.nacos.spring.core.env.NacosPropertySourcePostProcessor#postProcessBeanFactory

--->com.alibaba.nacos.spring.core.env.NacosPropertySourcePostProcessor#processPropertySource

--->com.alibaba.nacos.spring.core.env.NacosPropertySourcePostProcessor#addListenerIfAutoRefreshed

--->com.alibaba.nacos.spring.context.event.config.EventPublishingConfigService#addListener // [DelegatingEventPublishingListener] 做监听者

--->com.alibaba.nacos.spring.factory.CacheableEventPublishingNacosServiceFactory // 事件发布工厂

--->com.alibaba.nacos.spring.context.event.config.EventPublishingConfigService // 完成监听实例化

3.2 Bean 配置属性注册到Map>

-->org.springframework.context.support.AbstractApplicationContext#registerBeanPostProcessors

-->org.springframework.context.support.PostProcessorRegistrationDelegate#registerBeanPostProcessors

-->org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean

-->org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization

-->org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization

-->org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization

-->com.alibaba.nacos.spring.context.annotation.config.NacosValueAnnotationBeanPostProcessor#postProcessBeforeInitialization

-->com.alibaba.nacos.spring.context.annotation.config.NacosValueAnnotationBeanPostProcessor#doWithFields

-->com.alibaba.nacos.spring.context.annotation.config.NacosValueAnnotationBeanPostProcessor#doWithAnnotation

[com.alibaba.nacos.spring.context.annotation.config.NacosValueAnnotationBeanPostProcessor.NacosValueTarget]

// 完成-->com.alibaba.nacos.spring.context.annotation.config.NacosValueAnnotationBeanPostProcessor#doWithFields 初始化到改MAP中

3.3 长轮询监听到变更

立即刷新CacheData,调用listener [DelegatingEventPublishingListener]监听者发送context事件

// 当收到推送事件之后---->包装容器上下文事件----->主动更新MAP对应的bean实例属性

--->com.alibaba.nacos.spring.context.event.config.DelegatingEventPublishingListener#receiveConfigInfo

--->com.alibaba.nacos.spring.context.event.config.DelegatingEventPublishingListener#publishEvent

--->com.alibaba.nacos.spring.context.event.DeferredApplicationEventPublisher // 使用默认的publisher

--->com.alibaba.nacos.spring.context.event.DeferredApplicationEventPublisher#publishEvent // 触发容器事件

--->com.alibaba.nacos.spring.context.annotation.config.NacosValueAnnotationBeanPostProcessor#onApplicationEvent

因为有着Map记录了,占位符和所属实例的关系,所以依靠反射轻松改变了bean的配置值

18e658fb2fae9c68d1cba77fab69f2ed.png

--->com.alibaba.nacos.spring.context.annotation.config.NacosValueAnnotationBeanPostProcessor#setField

--->ReflectionUtils.makeAccessible(field);

field.set(bean, convertIfNecessary(field, propertyValue));

4 完成配置动态刷新

依靠反射轻松改变了bean的配置值

5 小结:

注意LOGGER 依赖关系,nacos输出日志

springboot 引入starter常用套路

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值