Nacos配置中心設計原理分析
一、怎么判斷配置發(fā)生了變化
我們在使用Nacos的時候,在Console對配置進行更改后,不用重啟服務,只要配置發(fā)生變化就能生效,那么Nacos是怎么判斷配置發(fā)生了變化呢?
Nacos的配置中支持多中格式,比如yml,properties,xml,json等,當然,使用yml格式的應該占大部分!
不過可以肯定的是,無論使用的是那種格式,數(shù)據(jù)都是鍵值對的形式,所以我們有一種實現(xiàn)方式,就是將配置轉換為一個Map保存下來,當通過控制臺或者API對配置進行變更的時候,我們將變更的數(shù)據(jù)和保存下來的Map中的值進行一一比對,如果有發(fā)生變化的那么就更新變化的那個key的value值。
不過上面這種方案的話開銷有點大,因為需要去解析配置文件,然后去對比每一個key。
Nacos的實現(xiàn)方式是通過對配置進行MD5加密,當配置發(fā)生變更,那么就對變更后的配置進行MD5加密,然后和本地的MD5進行比對,如果相同則代表配置沒發(fā)生變更,MD5值不同則代表發(fā)生了變更,則需要推送變更的配置到服務里面。
雖然使用進行MD5加密有一定的開銷,但是也是在能接受的范圍內。
核心代碼如下,當監(jiān)聽器收到配置變更后,會判斷和本地的MD5是否一樣,不一樣則推送變更的配置。

二、怎么觸發(fā)變更
在Nacos啟動的時候,會在后臺啟動一個線程去比對配置信息變更情況,不過并不是使用死循環(huán)不斷去獲取,廢話不多說,直接上核心代碼。

Nacos中巧妙的使用了隊列的poll來實現(xiàn)配置變更的實時拉取,圖中圈出來的listenExecutebell,bell的意思是鈴聲,listenExecutebell是一個隊列,使用了它的poll的超時方法,也就是說如果沒有從listenExecutebell中獲取到元素,那么就會阻塞,Nacos中阻塞50s,當獲取到元素,立馬往下執(zhí)行。
為什么要這樣做呢!
我們想一下,如果不使用這種方式,而是使用輪詢的方式去處理,比如1s或者5s去獲取一次,那么如果配置一直都沒有變更,一直發(fā)起請求,這將會增加服務的壓力,還有因為是輪詢的方式,數(shù)據(jù)也不能保證能夠實時。
Nacos1.X采用的是輪詢分方式,后面進行了更改,比如我們從控制臺或者通過API更改了配置信息,那么當客戶端收到服務端配置變更的通知后,就會去調用notifyListenConfig()方法。

notifyListenConfig()方法就是往listenExecutebell隊列中添加元素,當listenExecutebell中有元素時,就會去執(zhí)行executeConfigListen()方法,這個方法就是去執(zhí)行配置比對的相關操作。
所以總結下來,當配置信息發(fā)生變化的時候,就會主動去觸發(fā)本地配置更新操作,不僅保證了實時,也不會像輪詢那樣占用資源。
三、服務故障數(shù)據(jù)怎么保證
因為配置信息屬于需要很頻繁訪問的數(shù)據(jù),所以是存儲在內存中的,不過存儲在內存中數(shù)據(jù)當機器發(fā)生故障的時候會丟失,那么Nacos是怎么來解決這個問題的呢?
首先如果我們要保證Nacos的高可用,高可靠,數(shù)據(jù)持久化是一定要做的,Nacos支持數(shù)據(jù)庫持久化,我們可以使用Mysql來存儲配置信息。
當服務出現(xiàn)故障重啟后,Nacos會從數(shù)據(jù)庫中獲取數(shù)據(jù),然后保存到內存中,如下,使用@PostConstruct標注init()方法,那么在啟動時會執(zhí)行這個方法。

Nacos的配置除了保存在內存,數(shù)據(jù)庫中,還會保存在本地文件里,所以Nacos故障重啟后,也會清理掉本地文件,然后重新生成,這樣才能保證數(shù)據(jù)正確。
四、數(shù)據(jù)一致性
如果是Nacos單節(jié)點,就不存在數(shù)據(jù)一致性問題,但是當Nacos是集群部署時,就要考慮各節(jié)點數(shù)據(jù)一致問題了,所以就得引入共識機制。
Nacos使用的共識算法是JRaft和Distro,JRaft是強一致性算法,而Distro是最終一致性算法。
對于Nacos的共識機制,可以去官方文檔上進行詳細查看,這里不進行展開敘述了。
以上就是Nacos配置中心設計原理分析的詳細內容,更多關于Nacos配置中心的資料請關注腳本之家其它相關文章!
相關文章
spring cloud gateway集成hystrix全局斷路器操作
這篇文章主要介紹了spring cloud gateway集成hystrix全局斷路器操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-07-07
SpringBoot設置靜態(tài)資源訪問控制和封裝集成方案
這篇文章主要介紹了SpringBoot靜態(tài)資源訪問控制和封裝集成方案,關于springboot靜態(tài)資源訪問的問題,小編是通過自定義webconfig實現(xiàn)WebMvcConfigurer,重寫addResourceHandlers方法,具體完整代碼跟隨小編一起看看吧2021-08-08
SpringBoot + thymeleaf 實現(xiàn)讀取視頻列表并播放視頻功能
這篇文章主要介紹了SpringBoot + thymeleaf 實現(xiàn)讀取視頻列表并播放視頻功能,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-04-04
SpringBoot @Cacheable自定義KeyGenerator方式
這篇文章主要介紹了SpringBoot @Cacheable自定義KeyGenerator方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-12-12

