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