Nacos配置中心設(shè)計原理分析
一、怎么判斷配置發(fā)生了變化
我們在使用Nacos的時候,在Console對配置進(jìn)行更改后,不用重啟服務(wù),只要配置發(fā)生變化就能生效,那么Nacos是怎么判斷配置發(fā)生了變化呢?
Nacos的配置中支持多中格式,比如yml,properties,xml,json等,當(dāng)然,使用yml格式的應(yīng)該占大部分!
不過可以肯定的是,無論使用的是那種格式,數(shù)據(jù)都是鍵值對的形式,所以我們有一種實(shí)現(xiàn)方式,就是將配置轉(zhuǎn)換為一個Map保存下來,當(dāng)通過控制臺或者API對配置進(jìn)行變更的時候,我們將變更的數(shù)據(jù)和保存下來的Map中的值進(jìn)行一一比對,如果有發(fā)生變化的那么就更新變化的那個key的value值。
不過上面這種方案的話開銷有點(diǎn)大,因?yàn)樾枰ソ馕雠渲梦募?,然后去對比每一個key。
Nacos的實(shí)現(xiàn)方式是通過對配置進(jìn)行MD5加密,當(dāng)配置發(fā)生變更,那么就對變更后的配置進(jìn)行MD5加密,然后和本地的MD5進(jìn)行比對,如果相同則代表配置沒發(fā)生變更,MD5值不同則代表發(fā)生了變更,則需要推送變更的配置到服務(wù)里面。
雖然使用進(jìn)行MD5加密有一定的開銷,但是也是在能接受的范圍內(nèi)。
核心代碼如下,當(dāng)監(jiān)聽器收到配置變更后,會判斷和本地的MD5是否一樣,不一樣則推送變更的配置。
二、怎么觸發(fā)變更
在Nacos啟動的時候,會在后臺啟動一個線程去比對配置信息變更情況,不過并不是使用死循環(huán)不斷去獲取,廢話不多說,直接上核心代碼。
Nacos中巧妙的使用了隊列的poll來實(shí)現(xiàn)配置變更的實(shí)時拉取,圖中圈出來的listenExecutebell
,bell的意思是鈴聲,listenExecutebell是一個隊列,使用了它的poll的超時方法,也就是說如果沒有從listenExecutebell中獲取到元素,那么就會阻塞,Nacos中阻塞50s,當(dāng)獲取到元素,立馬往下執(zhí)行。
為什么要這樣做呢!
我們想一下,如果不使用這種方式,而是使用輪詢的方式去處理,比如1s或者5s去獲取一次,那么如果配置一直都沒有變更,一直發(fā)起請求,這將會增加服務(wù)的壓力,還有因?yàn)槭禽喸兊姆绞?,?shù)據(jù)也不能保證能夠?qū)崟r。
Nacos1.X采用的是輪詢分方式,后面進(jìn)行了更改,比如我們從控制臺或者通過API更改了配置信息,那么當(dāng)客戶端收到服務(wù)端配置變更的通知后,就會去調(diào)用notifyListenConfig()方法。
notifyListenConfig()方法就是往listenExecutebell隊列中添加元素,當(dāng)listenExecutebell中有元素時,就會去執(zhí)行executeConfigListen()方法,這個方法就是去執(zhí)行配置比對的相關(guān)操作。
所以總結(jié)下來,當(dāng)配置信息發(fā)生變化的時候,就會主動去觸發(fā)本地配置更新操作,不僅保證了實(shí)時,也不會像輪詢那樣占用資源。
三、服務(wù)故障數(shù)據(jù)怎么保證
因?yàn)榕渲眯畔儆谛枰茴l繁訪問的數(shù)據(jù),所以是存儲在內(nèi)存中的,不過存儲在內(nèi)存中數(shù)據(jù)當(dāng)機(jī)器發(fā)生故障的時候會丟失,那么Nacos是怎么來解決這個問題的呢?
首先如果我們要保證Nacos的高可用,高可靠,數(shù)據(jù)持久化是一定要做的,Nacos支持?jǐn)?shù)據(jù)庫持久化,我們可以使用Mysql來存儲配置信息。
當(dāng)服務(wù)出現(xiàn)故障重啟后,Nacos會從數(shù)據(jù)庫中獲取數(shù)據(jù),然后保存到內(nèi)存中,如下,使用@PostConstruct標(biāo)注init()方法,那么在啟動時會執(zhí)行這個方法。
Nacos的配置除了保存在內(nèi)存,數(shù)據(jù)庫中,還會保存在本地文件里,所以Nacos故障重啟后,也會清理掉本地文件,然后重新生成,這樣才能保證數(shù)據(jù)正確。
四、數(shù)據(jù)一致性
如果是Nacos單節(jié)點(diǎn),就不存在數(shù)據(jù)一致性問題,但是當(dāng)Nacos是集群部署時,就要考慮各節(jié)點(diǎn)數(shù)據(jù)一致問題了,所以就得引入共識機(jī)制。
Nacos使用的共識算法是JRaft和Distro,JRaft是強(qiáng)一致性算法,而Distro是最終一致性算法。
對于Nacos的共識機(jī)制,可以去官方文檔上進(jìn)行詳細(xì)查看,這里不進(jìn)行展開敘述了。
以上就是Nacos配置中心設(shè)計原理分析的詳細(xì)內(nèi)容,更多關(guān)于Nacos配置中心的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
java多線程CountDownLatch與線程池ThreadPoolExecutor/ExecutorService案
這篇文章主要介紹了java多線程CountDownLatch與線程池ThreadPoolExecutor/ExecutorService案例,2021-02-02手把手教你搭建第一個Spring Batch項(xiàng)目的步驟
這篇文章主要介紹了手把手教你搭建第一個Spring Batch項(xiàng)目的步驟,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09深入淺出分析Java抽象類和接口【功能,定義,用法,區(qū)別】
這篇文章主要介紹了Java抽象類和接口,結(jié)合實(shí)例形式深入淺出的分析了java抽象類與接口的功能功能,定義,用法及區(qū)別,需要的朋友可以參考下2017-08-08