vlambda博客
学习文章列表

Nacos 1.4.x 配置管理交互 与 源码简解

以一次 配置推送 解析整个交互过程,理解 Nacos 配置管理的架构;

背景知识:长轮训 long-polling,仅需此一遭便可理解。





1. Nacos-0 处理 long-polling 的过程,holding 时会放入 queue,等候 LocalDataChangeEvent 通知并处理变更配置(告知客户端)


2. Nacos-1 处理 publish-config 的过程,先写数据库,再发出一个 ConfigDataChangeEvent ,再由 AsyncTask 告知 all Members


3. 处理 DumpTask 的过程,主要是把 数据库为准 的配置 dump 入 DiskFile and MemoryCache

 a. 然后发布一个事件 LocalDataChangeEvent ,转而告知了 (1)


4. Nacos-2 处理 get-config 的过程,先读 MemoryCache 匹配并获取配置信息,配置内容在 DiskFile 直接 channel.transfer 返回


Nacos 1.4.x 配置管理交互 与 源码简解


针对 AsyncTask 通知所有集群成员 (包括自己)

  • 好处是更平等地对待集群内的所有成员,这样发起者自身在处理 DumpTask 不至于提前太多;

    • 若本地内优先处理,由于 LocalDataChangeEvent 让 客户端 长轮训 返回,客户端发起配置获取时,存在延时 其他节点 尚未 DumpTask 结束,所以会拿到旧配置;

    • 然后再发起 long-polling 才可能感知到 md5 有变化而获取到最新配置;

    • 最糟糕情况是还没 DumpTask 结束,要 30s 超时后才获得最新变更。




## 简解源码 > 走读

注:... 表示异步执行,* 标识重点


### Long-polling  .getConfigChange

ConfigController.listener() // The client listens for configuration changes. ConfigServletInner.doPollingConfig() LongPollingService.addLongPollingClient() ... ClientLongPolling.run() create ScheduledFuture: asyncTimeoutFuture // timeout with return null Queue<ClientLongPolling> allSubs.add(ClientLongPolling.this); ... **LocalDataChangeEvent** *// 关键的配置变更事件* ... DataChangeTask.run() Queue<ClientLongPolling> allSubs.iterator() // compare and return changeGroupKeys

Nacos 1.4.x 配置管理交互 与 源码简解


### Publish config  .change Config

ConfigController.publishConfig() // Adds or updates non-aggregated data. **PersistService.insertOrUpdate()** *// write into db first* **NotifyCenter.publishEvent > ConfigDataChangeEvent** *// 关键配置变更事件* ... AsyncNotifyService.onEvent() ConfigExecutor.executeAsyncNotify(new AsyncTask(nacosAsyncRestTemplate, queue)) // async task in queue ... AsyncTask.run() executeAsyncInvoke() restTemplate url:(**/v1/cs/communication/dataChange**) // rest get url to notify all members.

Nacos 1.4.x 配置管理交互 与 源码简解


#### Notify data change  // all members.

CommunicationController.notifyConfigInfo() DumpService.dump() TaskManager.addTask(taskKey, new DumpTask(..)) ... DumpProcessor.process() **PersistService.findConfigInfo()** *// get config from db* DumpConfigHandler.configDump(ConfigDumpEvent) DumpConfigHandler.configDump() ConfigCacheService.dump() **DiskUtil.saveToDisk(dataId, group, tenant, content)** *// dump in disk first* ConfigCacheService.updateMd5() MemoryCache.update() *// dump in memory second*                                NotifyCenter.publishEvent > **LocalDataChangeEvent**  *// 关键的配置变更事件*

Nacos 1.4.x 配置管理交互 与 源码简解



Nacos 1.4.x 配置管理交互 与 源码简解