SpringCloud(二) Nacos作爲配置中心——配置更新原理

Nacos 服務端創建了相關的配置項後,客戶端就可以進行監聽了。客戶端是通過一個定時任務來檢查自己監聽的配置項的數據的,一旦服務端的數據發生變化時,客戶端將會獲取到最新的數據,並將最新的數據保存在一個 CacheData 對象中,然後會重新計算 CacheData 的 md5 屬性的值,此時就會對該 CacheData 所綁定的 Listener 觸發 receiveConfigInfo 回調。

考慮到服務端故障的問題,客戶端將最新數據獲取後會保存在本地的 snapshot 文件中,以後會優先從文件中獲取配置信息的值。

那麼客戶端如何感知到數據發生變化的呢?

  我們知道客戶端會有一個長輪訓的任務去檢查服務器端的配置是否發生了變化,如果發生了變更,那麼客戶端會拿到變更的 groupKey 再根據 groupKey 去獲取配置項的最新值更新到本地的緩存以及文件中,那麼這種每次都靠客戶端去請求,那請求的時間間隔設置多少合適呢?
長輪訓的概念:
  客戶端發起一個請求到服務端,服務端收到客戶端的請求後,並不會立刻響應給客戶端,而是先把這個請求hold住,然後服務端會在hold住的這段時間檢查數據是否有更新,如果有,則響應給客戶端,如果一直沒有數據變更,則達到一定的時間(長輪訓時間間隔)才返回。
  長輪訓典型的場景有: 掃碼登錄、掃碼支付。

 

timeout是在init這個方法中賦值的,默認情況下是30秒,可以通過configLongPollTimeout進行修改,但是源碼中delayTime字段用於作爲結束監聽返回數據的時間間隔,所以等待的時間一般是略小於30秒。

ClientLongPolling 被提交給 scheduler 執行之後,實際執行的內容可以拆分成以下四個步驟:

  • 1.創建一個調度的任務,調度的延時時間爲 29.5s
  • 2.將該 ClientLongPolling 自身的實例添加到一個 allSubs 中去
  • 3.延時時間到了之後,首先將該 ClientLongPolling 自身的實例從 allSubs 中移除
  • 4.獲取服務端中保存的對應客戶端請求的 groupKeys 是否發生變更,將結果寫入 response 返回給客戶端

在過程中總共分兩種情況,第一種在監聽過程中發生變化,第二種就是超時之後執行檢測後返回

第一種(等待期發生變化)

第二種(等待期未發生變化)

最後通過一些問題來加強理解

  • nacos是採用推還是拉

實時感知是建立在客戶端拉和服務端“推”的基礎上,但是這裏的服務端“推”需要打上引號,因爲服務端和客戶端直接本質上還是通過 http 進行數據通訊的,之所以有“推”的感覺,是因爲服務端主動將變更後的數據通過 http 的 response 對象提前寫入了。

  • 客戶端長輪詢的響應時間會受什麼影響

客戶端長輪詢的響應時間,設置的是30s,但是有時響應很快,有時響應很慢,這取決於服務端的配置有沒有發生變化。當配置發生變化時,響應很快就會返回,當配置一直沒有發生變化時,會等到 29.5s 之後再進行響應。

  • 爲什麼更改了配置信息後客戶端會立即得到響應

因爲服務端會在更改了配置信息後,找到具體的客戶端請求中的 response,然後直接將結果寫入 response 中,就像服務端對客戶端進行的數據 “推送” 一樣,所以客戶端會很快得到響應。

  • 客戶端的超時時間爲什麼要設置爲30s

這應該是一個經驗值,該超時時間關係到服務端調度任務的等待時間,服務端在前29.5s 只需要進行等待,最後的 0.5s 才進行配置變更檢查。

 

參考文章:

https://www.jianshu.com/p/acb9b1093a54

https://www.cnblogs.com/wuzhenzhao/p/11385079.html

 

發佈了92 篇原創文章 · 獲贊 179 · 訪問量 60萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章