前言
生產環(huán)境需要使用 K8S 部署方式,并且依賴于 Nacos 發(fā)布云配置酬蹋,但是需要支持按 Pod 分批發(fā)布身笤。目前 Nacos 僅支持兩段式發(fā)布,先發(fā)一部分試點斤彼,剩下的需要全部發(fā)布或者試點的全部回滾分瘦,不滿足于需求,需基于 Nacos 基礎上進行處理琉苇。Nacos 官方對于發(fā)布 Beta 功能的介紹:https://nacos.io/en-us/blog/nacos%201.1.0.html
原功能介紹(基于1.3.0版本)
Nacos 發(fā)布 Beta 功能從下圖來看嘲玫,發(fā)布了 Beta 之后,就無法再修改內容和 Beta 發(fā)布的 IP并扇,只能操作停止 Beta 和發(fā)布兩個按鈕去团,但是我們也可以通過 API 直接調用去更新betaIps
參數(shù)
入口為com.alibaba.nacos.config.server.controller.ConfigController#publishConfig
,從下圖可以看出,如果傳了betaIps
土陪,調用該方法persistService.insertOrUpdateBeta
該方法具體實現(xiàn)如下
在這里我們關注的是updateConfigInfo4Beta
方法具體實現(xiàn)
從實現(xiàn)可看出昼汗,并沒有將betaIps
字段進行更新,所以betaIps
字段創(chuàng)建了之后就無法再更新了
并且鬼雀,從updateConfigInfo4Beta
實現(xiàn)中可以看出顷窒,操作完數(shù)據(jù)后,還會發(fā)出一個事件源哩,該事件會將匹配的dataId
調用/nacos/v1/cs/communication/dataChange
接口蹋肮,由dataChange
接口通知具體匹配的監(jiān)聽該dataId
客戶端
communication/dataChange
接口具體實現(xiàn)如下
dumpService.dump
中會執(zhí)行DumpTask#process
方法
該方法會從數(shù)據(jù)庫config_info_beat
查詢數(shù)據(jù)再調用DumpConfigHandler.configDump
,從上圖可以看出build.remove
中的參數(shù)如果為 null璧疗,那么event.isRemove
就為 true坯辩,但是我們需要更新的必定不會為 null,所以執(zhí)行的是 else 中的邏輯
ConfigCacheService.dumpBeta
具體實現(xiàn)崩侠,拿從數(shù)據(jù)庫獲取的配置內容進行 MD5 處理漆魔,再進行updateBetaMd5
updateBetaMd5
具體實現(xiàn),獲取內存 MD5 和新生成的 MD5 進行比較却音,如果有變化才會觸發(fā)LocalDataChangeEvent
事件
LocalDataChangeEvent
事件具體在LongPollingService#onEvent
方法中執(zhí)行改抡,通過DataChangeTask
進行通知客戶端內容變更
結論
那么如何才能更新betaIps
字段?由于接口無法對betaIps
字段進行更新系瓢,那我們是否可以直接操作數(shù)據(jù)庫阿纤?從源碼來看,是由communication/dataChange
接口去通知客戶端配置內容變更
我們通過實踐發(fā)現(xiàn)夷陋,直接修改config_info_beta
表中的betaips
和content
字段欠拾,再調用communication/dataChange
接口,由于updateBetaMd5
方法中判斷 MD5 是否有變化骗绕,有變化的情況下才會觸發(fā)LocalDataChangeEvent
事件藐窄,才會通知到客戶端
- 已驗證過在
1.3.0
版本和2.0.1
版本都有效,雖然大版本差異源碼有所不同酬土,但是大邏輯沒變- 調用
communication/dataChange
接口時荆忍,如果 Nacos 有多個節(jié)點,則需要每個節(jié)點調用一次communication/dataChange
接口撤缴,但調用時需每個節(jié)點間間隔一下刹枉,避免同一個客戶端注冊到多個 Nacos 節(jié)點上時,同時通知更新配置導致客戶端出現(xiàn)異常- 若需要在已添加的
betaips
中修改IP
屈呕,只變更注釋內容是不生效的微宝,需要變更配置內容