您好,登錄后才能下訂單哦!
本篇內容介紹了“如何掌握Nacos高可用特性”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
前言
服務注冊發現是一個經久不衰的話題,Dubbo 早期開源時默認的注冊中心 Zookeeper 最早進入人們的視線,并且在很長一段時間里,人們將注冊中心和 Zookeeper 劃上了等號,可能 Zookeeper 的設計者都沒有想到這款產品對微服務領域造成了如此深厚的影響,直到 SpringCloud 開始流行,其自帶的 Eureka 進入了人們的視野,人們這才意識到原來注冊中心還可以有其他的選擇。再到后來,熱衷于開源的阿里把目光也聚焦在了注冊中心這個領域,Nacos 橫空出世。
注冊中心
Kirito 在做注冊中心選型時的思考:曾經我沒得選,現在我只想選擇一個好的注冊中心,它最好是開源的,這樣開放透明,有自我的掌控力;不僅要開源,它還要有活躍的社區,以確保特性演進能夠滿足日益增長的業務需求,出現問題也能即使修復;最好...它的功能還要很強大,除了滿足注冊服務、推送服務外,還要有完善的微服務體系中所需的功能;最重要的,它還要穩定,最好有大廠的實際使用場景背書,證明這是一個經得起實戰考驗的產品;當然,云原生特性,安全特性也是很重要的...
似乎 Kirito 對注冊中心的要求實在是太高了,但這些五花八門的注冊中心呈現在用戶眼前,總是免不了一番比較。正如上面所言,功能特性、成熟度、可用性、用戶體驗度、云原生特性、安全都是可以拉出來做比較的話題。今天這篇文章重點介紹的是 Nacos 在可用性上體現,希望借助于這篇文章,能夠讓你對 Nacos 有一個更加深刻的認識。
高可用介紹
當我們在聊高可用時,我們在聊什么?
系統可用性達到 99.99%
在分布式系統中,部分節點宕機,依舊不影響系統整體運行
服務端集群化部署多個節點
這些都可以認為是高可用,而我今天介紹的 Nacos 高可用,則是一些 Nacos 為了提升系統穩定性而采取的一系列手段。Nacos 的高可用不僅僅存在于服務端,同時它也存在于客戶端,以及一些與可用性相關的功能特性中。這些點組裝起來,共同構成了 Nacos 的高可用。
客戶端重試
先統一一下語義,在微服務架構中一般會有三個角色:Consumer、Provider 和 Registry,在今天注冊中心的主題中,Registry 是 nacos-server,而 Consumer 和 Provider 都是 nacos-client。
在生產環境,我們往往需要搭建 Nacos 集群,在 Dubbo 也需要顯式地配置上集群地址:
<dubbo:registry protocol="nacos" address="192.168.0.1:8848,192.168.0.2:8848,192.168.0.3:8848"/>
當其中一臺機器宕機時,為了不影響整體運行,客戶端會存在重試機制
輪詢 server
邏輯非常簡單,拿到地址列表,在請求成功之前逐個嘗試,直到成功為止。
該可用性保證存在于 nacos-client 端。
一致性協議 distro
首先給各位讀者打個強心劑,不用看到”一致性協議“這幾個字就被勸退,本節不會探討一致性協議的實現過程,而是重點介紹其余高可用相關的特性。有的文章介紹 Nacos 的一致性模型是 AP + CP,這么說很容易讓人誤解,其實 Nacos 并不是支持兩種一致性模型,也并不是支持兩種模型的切換,介紹一致性模型之前,需要先了解到 Nacos 中的兩個概念:臨時服務和持久化服務。
臨時服務(Ephemeral):臨時服務健康檢查失敗后會從列表中刪除,常用于服務注冊發現場景。
持久化服務(Persistent):持久化服務健康檢查失敗后會被標記成不健康,常用于 DNS 場景。
臨時服務使用的是 Nacos 為服務注冊發現場景定制化的私有協議 distro,其一致性模型是 AP;而持久化服務使用的是 raft 協議,其一致性模型是 CP。所以以后不要再說 Nacos 是 AP + CP 了,更建議加上服務節點狀態或者使用場景的約束。
distro 協議與高可用有什么關系呢?上一節我們提到 nacos-server 節點宕機后,客戶端會重試,但少了一個前提,即 nacos-server 少了一個節點后依舊可以正常工作。Nacos 這種有狀態的應用和一般無狀態的 Web 應用不同,并不是說只要存活一個節點就可以對外提供服務的,需要分 case 討論,這與其一致性協議的設計有關。distro 協議的工作流程如下:
Nacos 啟動時首先從其他遠程節點同步全部數據
Nacos 每個節點是平等的都可以處理寫入請求,同時把新數據同步到其他節點
每個節點只負責部分數據,定時發送自己負責數據校驗值到其他節點來保持數據一致性
集群正常狀態
如上圖所示,每個節點服務一部分服務的讀寫,但每個節點都可以接收到讀寫請求,這時就存在兩種讀寫情況:
當該節點接收到屬于該節點負責的服務時,直接讀寫。
當該節點接收到不屬于該節點負責的服務時,將在集群內部路由,轉發給對應的節點,從而完成讀寫。
而當節點發生宕機后,原本該節點負責的一部分服務的讀寫任務會轉移到其他節點,從而保證 Nacos 集群整體的可用性。
部分節點宕機
一個比較復雜的情況是,節點沒有宕機,但是出現了網絡分區,即下圖所示:
網絡分區
這個情況會損害可用性,客戶端會表現為有時候服務存在有時候服務不存在。
綜上,Nacos 的 distro 一致性協議可以保證在大多數情況下,集群中的機器宕機后依舊不損害整體的可用性。該可用性保證存在于 nacos-server 端。
本地緩存文件 Failover 機制
注冊中心發生故障最壞的一個情況是整個 Server 端宕機,這時候 Nacos 依舊有高可用機制做兜底。
一道經典的 Dubbo 面試題:當 Dubbo 應用運行時,Nacos 注冊中心宕機,會不會影響 RPC 調用。這個題目大多數應該都能回答出來,因為 Dubbo 內存里面是存了一份地址的,一方面這樣的設計是為了性能,因為不可能每次 RPC 調用時都讀取一次注冊中心,另一面,這也起到了可用性的保障(盡管可能 Dubbo 設計者并沒有考慮這個因素)。
那如果,我在此基礎上再出一道 Dubbo 面試題:Nacos 注冊中心宕機,Dubbo 應用發生重啟,會不會影響 RPC 調用。如果了解了 Nacos 的 Failover 機制,應當得到和上一題同樣的回答:不會。
Nacos 存在本地文件緩存機制,nacos-client 在接收到 nacos-server 的服務推送之后,會在內存中保存一份,隨后會落盤存儲一份快照。snapshot 默認的存儲路徑為:{USER_HOME}/nacos/naming/ 中
Nacos snapshot 文件目錄
這份文件有兩種價值,一是用來排查服務端是否正常推送了服務;二是當客戶端加載服務時,如果無法從服務端拉取到數據,會默認從本地文件中加載。
前提是構建 NacosNaming 時傳入了該參數:namingLoadCacheAtStart=true
Dubbo 2.7.4 及以上版本支持該 Nacos 參數;開啟該參數的方式:dubbo.registry.address=nacos://127.0.0.1:8848?namingLoadCacheAtStart=true
在生產環境,推薦開啟該參數,以避免注冊中心宕機后,導致服務不可用的穩定,在服務注冊發現場景,可用性和一致性 trade off 時,我們大多數時候會優先考慮可用性。
細心的讀者還注意到 {USER_HOME}/nacos/naming/{namespace} 下除了緩存文件之外還有一個 failover 文件夾,里面存放著和 snapshot 一致的文件夾。這是 Nacos 的另一個 failover 機制,snapshot 是按照某個歷史時刻的服務快照恢復恢復,而 failover 中的服務可以人為修改,以應對一些極端場景。
該可用性保證存在于 nacos-client 端。
心跳同步服務
心跳機制一般廣泛存在于分布式通信領域,用于確認存活狀態。一般心跳請求和普通請求的設計是有差異的,心跳請求一般被設計的足夠精簡,這樣在定時探測時可以盡可能避免性能下降。而在 Nacos 中,處于可用性的考慮,一個心跳報文包含了全部的服務信息,這樣相比僅僅發送探測信息降低了吞吐量,而提升了可用性,怎么理解呢?考慮以下的兩種場景:
nacos-server 節點全部宕機,服務數據全部丟失。nacos-server 即使恢復運作,也無法恢復出服務,而心跳包含全部內容可以在心跳期間就恢復出服務,保證可用性。
nacos-server 出現網絡分區。由于心跳可以創建服務,從而在極端網絡故障下,依舊保證基礎的可用性。
以下是對心跳同步服務的測試,使用阿里云 MSE 提供 Nacos 集群進行測試
調用 OpenApi:curl -X "DELETE mse-xxx-p.nacos-ans.mse.aliyuncs.com:8848/nacos/v1/ns/service?serviceName=providers:com.alibaba.edas.boot.EchoService:1.0.0:DUBBO&groupName=DEFAULT_GROUP" 依次刪除各個服務
過 5s 后刷新,服務又再次被注冊了上來,符合我們對心跳注冊服務的預期。
集群部署模式高可用
最后給大家分享的 Nacos 高可用特性來自于其部署架構。
節點數量
我們知道在生產集群中肯定不能以單機模式運行 Nacos,那么第一個問題便是:我應該部署幾臺機器?前面我們提到 Nacos 有兩個一致性協議:distro 和 raft,distro 協議不會有腦裂問題,所以理論來說,節點數大于等于 2 即可;raft 協議的投票選舉機制則建議是 2n+1 個節點。綜合來看,選擇 3 個節點是起碼的,其次處于吞吐量和更高可用性的考量,可以選擇 5 個,7 個,甚至 9 個節點的集群。
多可用區部署
組成集群的 Nacos 節點,應該盡可能考慮兩個因素:
各個節點之間的網絡時延不能很高,否則會影響數據同步
各個節點所處機房、可用區應當盡可能分散,以避免單點故障
以阿里云的 ECS 為例,選擇同一個 Region 的不同可用區就是一個很好的實踐
部署模式
主要分為 K8s 部署和 ECS 部署兩種模式。
ECS 部署的優點在于簡單,購買三臺機器即可搭建集群,如果你熟練 Nacos 集群部署的話,這不是難事,但無法解決運維問題,如果 Nacos 某個節點出現 OOM 或者磁盤問題,很難迅速摘除,無法實現自運維。
K8s 部署的有點在于云原生運維能力強,可以在節點宕機后實現自恢復,保障 Nacos 的平穩運行。前面提到過,Nacos 和無狀態的 Web 應用不同,它是一個有狀態的應用,所以在 K8s 中部署,往往要借助于 StatefulSet 和 Operator 等組件才能實現 Nacos 集群的部署和運維。
MSE Nacos 的高可用最佳實踐
阿里云 MSE(微服務引擎)提供了 Nacos 集群的托管能力,實現了集群部署模式的高可用。
當創建多個節點的集群時,系統會默認分配在不同可用區。同時,這對于用戶來說又是透明的,用戶只需要關心 Nacos 的功能即可,MSE 替用戶兜底可用性。
MSE 底層使用 K8s 運維模式部署 Nacos。歷史上出現過用戶誤用 Nacos 導致部分節點宕機的問題,但借助于 K8s 的自運維模式,宕機節點迅速被拉起,以至于用戶可能都沒有意識到自己發生宕機。
下面模擬一個節點宕機的場景,來看看 K8s 如何實現自恢復。
一個三節點的 Nacos 集群:
正常狀態
執行 kubectl delete pod mse-7654c960-1605278296312-reg-center-0-2 以模擬部分節點宕機的場景。
恢復中
大概 2 分鐘后,節點恢復,并且角色發生了轉換,Leader 從殺死的 2 號節點轉給 1 號節點
恢復后 leader 重選
“如何掌握Nacos高可用特性”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。