Nacos1.4.1配置中心源码分析
2025-02-26 14:47:45 0 举报
Nacos1.4.1配置中心源码分析,分享给大家学习。 更多干货,可以关注我的公众号:Fox爱分享
作者其他创作
大纲/内容
发布配置
响应到客户端
Queue<ClientLongPolling>
NacosConfigProperties
@Bean
MetricsHttpAgent#httpPost
加载顺序:1.文件名(微服务名称)2. 文件名.文件扩展名3.文件名-profile.文件扩展名优先级 3>2>1
持有NacosConfigProperties和ConfigService
ConfigCacheService#dump
RefreshScope#refreshAll
persistService.findConfigMaxId()
获取到配置文件
用于分页,每次捞取1000条配置刷进磁盘和内存
两个线程池:1.只有一个线程的线程池,用来执行定时任务,每隔10ms执行一次checkConfigInfo()2.线程数等于处理器个数的线程池,用来执行ClientWorker.LongPollingRunnable#run
Nacos配置中心启动相关的配置
获取配置中心服务ConfigService
加载扩展的配置文件,对应配置spring.cloud.nacos.config.extensionConfigs
NotifyCenter.publishEvent(event)
MD5Util#compareMd5
spring-cloud-context-2.2.5.RELEASE.jar!/META-INF/spring.factories
implements
prepareEnvironment
用来刷新容器中标记了@RefreshScope Bean的类
如果存在此配置文件,读取配置信息
NacosPropertySourceLocator
无论配置有没有更新,最终都会进行响应,延迟29.5s执行,然后会把自己添加到一个队列中
ClientLongPolling clientSub = iter.next()
NacosPropertySourceLocator#loadNacosDataIfPresent
GenericScope#destroy()
extends
思考:Nacos 在启动的时候是怎么将所有的配置文件信息 Dump 到磁盘上的
run
java.lang.Runnable#run
ConfigFactory#createConfigService
查询oldConfigInfo
checkConfigInfo()
获取新的参数值,并和之前得进行比较找出改变得参数值
客户端pull长轮询,出现异常延迟2秒执行
MetricsHttpAgent#httpGet
addListener
NacosRefreshProperties
更新配置,spring cloud的实现
NacosConfigService#getConfigInner
handle((ApplicationReadyEvent) event)
NacosRestTemplate#get
LongPollingService.DataChangeTask#run
获取配置并且注册监听器
subscriber.onEvent(event)
isRefreshEnabled()
如果未获取到配置信息,则远程调用配置中心获取配置信息
ApplicationContextInitializer
清除Scope里面的缓存,下次就会重新从BeanFactory获取一个新的实例(该实例使用新的配置)
nacosConfigManager.getConfigService()
insert
update
不支持长轮询
迭代allSubs队列
ConfigExecutor.executeLongPolling
spring-cloud-starter-alibaba-nacos-config-2.2.5.RELEASE.jar!/META-INF/spring.factories
更新当前配置
1.集群其他节点同步配置2.告诉客户端配置发生变更
客户端工作类
publishConfig
将数据库中的所有 ConfigInfo 查询出来写到服务器的磁盘中
全量Dump配置信息
RefreshAutoConfiguration
添加监听器
Spring的扩展点之一,在ConfigurableApplicationContext#refresh() 之前调用,通常用于需要对应用上下文做初始化的web应用中,比如根据上下文环境注册属性源或激活配置文件等
检查变更配置
检查本地的配置(容错配置)
extract(\t\t\t\tthis.context.getEnvironment().getPropertySources())
NacosContextRefresher
ClientLongPolling 被提交给 scheduler 执行,可以拆分成4个步骤:1.创建一个调度的任务,调度的延时时间为 29.5s2.将该 ClientLongPolling 自身的实例添加到一个 allSubs 中去3.延时时间到了之后,首先将该 ClientLongPolling 自身的实例从 allSubs 中移除4.获取服务端中保存的对应客户端请求的 groupKeys ,检查是否发生变更,将结果写入 response 返回给客户端
LongPollingService.ClientLongPolling#run
addConfigFilesToEnvironment()
DumpService#dumpOperate
EventPublishingRunListener#running
clientSub.sendResponse(Arrays.asList(groupKey))
NacosConfigBootstrapConfiguration
当用户发布配置,会回调listener
加载properties配置文件,优先加载bootstrap.properties,然后加载application.properties
RefreshScope
响应配置发生变化的key
向nacos server发出一个长连接30s超时,返回nacos server有更新过的dataIds
配置中心属性配置类,对应bootstrap.properties中的配置信息
allSubs.remove(ClientLongPolling.this)
每隔10ms执行一次定时任务
super.destroy()
LongPollingService初始化时订阅了LocalDataChangeEvent事件
源码入口
获取配置信息
NacosConfigService
长轮询
在Spring-cloud-context包中实现,通过SPI机制加载: SpringApplication初始化的过程中会通过SpringFactoriesLoader加载ApplicationContextInitializer类型的实现类到initializers中
服务端push模式
注意:这是Spring Cloud提供的接口。Spring Boot启动时调用PropertySourceLocator.locate(env)用来加载配置信息
NotifyCenter.registerSubscriber
context.publishEvent(new RefreshScopeRefreshedEvent())
持久化配置信息到mysql
NacosConfigService(Properties properties)
nacos config服务端获取配置接口
将配置保存到磁盘文件中
ClientWorker
Runnable#run
NacosContextRefresher#onApplicationEvent
ApplicationListener
loadSharedConfiguration(composite)
/nacos/v1/cs/configs
发布环境变更事件,并带上改变得参数值
对有变化的配置调用对应的监听器去处理
ConfigServletInner#doGetConfig
getConfig
NacosPropertySourceLocator#locate
优先使用本地配置
NacosConfigManager
调用NacosConfigService的构造器
删除配置
用来向nacos server发起请求的代理
支持长轮询的处理
延迟29.5s执行
添加刷新纪录
NacosConfigManager#createConfigService
根据变化的dataId调用nacos config服务端获取配置信息,并更新本地快照
SpringBoot提供的加载配置文件的接口
刷新refreshScope里面的bean实例
readTimeoutMs=45sheader参数:Long-Pulling-Timeout=30sLong-Pulling-Timeout-No-Hangup=true
RefreshEventListener#onApplicationEvent
ConfigController#listener
SpringApplication#run
loadExtConfiguration(composite)
ClientWorker.LongPollingRunnable
Post请求
SmartApplicationListener
Post请求:/nacos/v1/cs/configs
removeConfig
加载nacos配置中心的配置信息
handle((RefreshEvent) event)
保存旧的配置到历史记录
发布RefreshEvent事件,对应的监听器为RefreshEventListener
测试: http://127.0.0.1:8848/nacos/v1/cs/configs?dataId=common.yaml&group=DEFAULT_GROUP&tenant=39e1e969-15f9-46d2-832d-fa052da55377
服务端这边最多处理时长29.5s,需要留0.5s来返回,以免客户端那边超时
AsyncNotifyService
加载当前应用配置
通知订阅者,此处也利用了阻塞队列异步处理机制
NacosPropertySourceLocator#loadNacosPropertySource
MetricsHttpAgent
LongPollingService#LongPollingService
CacheData#safeNotifyListener
ConfigExecutor.scheduleLongPolling
是否刷新配置,默认true
调用服务端获取配置信息
保存结果到本地文件
dumpAllProcessor.process(new DumpAllTask())
注册监听器
sendResponse(changedGroups)
获取本地配置文件路径
cacheMap中缓存着需要刷新的配置,将cacheMap中的数量以3000分一个组,分别创建一个LongPollingRunnable用来监听配置更新
listener.receiveConfigInfo(contentTmp)
执行长连接任务
refreshContext(context)
集群模式下轮询获取一个服务调用节点发起调用ServerHttpAgent#httpGet
注意:不是去查mysql,而是去查本地磁盘的缓存,所以直接修改mysql配置是不行的。修改配置需要发布ConfigDataChangeEvent 的事件,触发本地文件和内存的更新。
registerNacosListenersForApplications()
加载共享的配置文件,对应配置spring.cloud.nacos.config.sharedConfigs
为每个dataId注册监听器
写入到服务器磁盘
checkLocalConfig(cacheData)
readFile(localPath)
从队列取任务执行
RefreshEventListener
LocalConfigInfoProcessor#saveSnapshot
发布ApplicationReadyEvent事件
NacosPropertySourceBuilder#loadNacosData
DefaultPublisher#notifySubscriber
把原来的environment里面的参数放到一个新建的Spring Context容器下重新加载,完事之后关闭新容器,这里就是获取参数的新值了
PropertySourceLoader
长轮询主要4个步骤:1. 检查本地配置,如果存在本地配置,并且与缓存中的本地配置版本不一样,把本地配置内容更新到缓存,并触发事件2. 向nacos config server发出一个长连接,30s超时,nacos config server会返回有变化的dataIds3. 根据变化的dataId,从服务端拉取最新的配置内容,并更新本地快照和缓存4. 对有变化的配置触发事件监听器来处理
ConfigFileApplicationListener.Loader#load
集群其他节点同步配置
删除监听器
allSubs.add(this)
listeners.running(context)
generateResponse(changedGroups)
从队列中移除当前任务
ExternalDumpService#init
监听ApplicationReadyEvent事件,并注册一个nacos listener用来监听nacos config配置修改后发布一个spring refreshEvent用来刷新配置和应用
getConfigAndSignListener
ConfigService
NacosRestTemplate#postForm
调用接口:http://127.0.0.1:8848/nacos/v1/cs/configs/listener
SELECT max(id) FROM config_info
直接与当前配置作比较,返回有变更的配置
cacheData.checkListenerMd5()
处理ApplicationReadyEvent事件
prepareContext
从mysql数据库分页查询所有配置
Subscriber#onEvent
Nacos配置中心服务
cache.md5 = md5;cache.lastModifiedTs = lastModifiedTs;NotifyCenter.publishEvent(new LocalDataChangeEvent(groupKey));
AbstractSharedListener#innerReceive
发起远程调用
初始化
用户通过nacos-console控制界面修改了配置,点击发布
写入磁盘
PropertySourceLocator
NacosConfigAutoConfiguration
PropertySourceBootstrapConfiguration#initialize
executorService.execute(this)
最终会调用
PropertiesPropertySourceLoader#load
触发ConfigDataChangeEvent事件
NacosRefreshHistory
当前有MD5不一致的,生成响应信息直接返回
/v1/cs/configs/listener
ContextRefresher#refresh
Get请求
removeListener
继续轮询
加载配置并合并到CompositePropertySource
ConfigServletInner#doPollingConfig
ContextRefresher
比较客户端的md5与当前server端的是否一致,不一致的返回到changedGroups
ConfigController#getConfig
executorService.execute(new LongPollingRunnable(i))
dumpConfigInfo(dumpAllProcessor)
用来存储标记了@RefreshScope注解的类的容器
处理RefreshEvent事件
PropertySourceLocator#locateCollection
ConfigController#publishConfig
Spring 构建bean的过程中会执行带有 @PostConstruct 的初始化方法
refreshEnvironment()
SpringBoot应用启动
用来触发刷新过程的对象
ClientWorker#getServerConfig
DumpService

收藏

收藏
0 条评论
下一页