架構設計之微服務註冊中心選型

ZooKeeper、Consul、Eureka和新生的Nacos 都實現了註冊中心的功能。那麼從哪些方面進行對比,進而選型呢?程序員

 

 

1.數據模型:網絡

註冊中心的核心數據是服務的名字和它對應的網絡地址,當服務註冊了多個實例時,咱們須要對不健康的實例進行過濾或者針對實例的一些特徵進行流量的分配,那麼就須要在實例上存儲一些例如健康狀態、權重等屬性。隨着服務規模的擴大,漸漸的又須要在整個服務級別設定一些權限規則、以及對全部實例都生效的一些開關,因而在服務級別又會設立一些屬性。再日後,咱們又發現單個服務的實例又會有劃分爲多個子集的需求,例如一個服務是多機房部署的,那麼可能須要對每一個機房的實例作不一樣的配置,這樣又須要在服務和實例之間再設定一個數據級別。數據結構

 

2.數據一致性:架構

數據一致性是分佈式系統永恆的話題,Paxos協議的艱深更讓數據一致性成爲程序員大牛們吹水的常見話題。不過從協議層面上看,一致性的選型已經很長時間沒有新的成員加入了。目前來看基本能夠歸爲兩家:一種是基於Leader的非對等部署的單點寫一致性,一種是對等部署的多寫一致性。負載均衡

 

3.負載均衡:框架

負載均衡嚴格的來講,並不算是傳統註冊中心的功能。通常來講服務發現的完整流程應該是先從註冊中心獲取到服務的實例列表,而後再根據自身的需求,來選擇其中的部分實例或者按照必定的流量分配機制來訪問不一樣的服務提供者,所以註冊中心自己通常不限定服務消費者的訪問策略。Eureka、Zookeeper包括Consul,自己都沒有去實現可配置及可擴展的負載均衡機制,Eureka的負載均衡是由ribbon來完成的,而Consul則是由Fabio作負載均衡。運維

服務端的負載均衡,給服務提供者更強的流量控制權,可是沒法知足不一樣的消費者但願使用不一樣負載均衡策略的需求。而不一樣負載均衡策略的場景,確實是存在的。而客戶端的負載均衡則提供了這種靈活性,並對用戶擴展提供更加友好的支持。可是客戶端負載均衡策略若是配置不當,可能會致使服務提供者出現熱點,或者壓根就拿不到任何服務提供者。分佈式

 

4.健康檢查:性能

Zookeeper和Eureka都實現了一種TTL的機制,就是若是客戶端在必定時間內沒有向註冊中心發送心跳,則會將這個客戶端摘除。Eureka作的更好的一點在於它容許在註冊服務的時候,自定義檢查自身狀態的健康檢查方法。這在服務實例可以保持心跳上報的場景下,是一種比較好的體驗,在Dubbo和SpringCloud這兩大致系內,也被培養成用戶心智上的默認行爲。Nacos也支持這種TTL機制,不過這與ConfigServer在阿里巴巴內部的機制又有一些區別。Nacos目前支持臨時實例使用心跳上報方式維持活性,發送心跳的週期默認是5秒,Nacos服務端會在15秒沒收到心跳後將實例設置爲不健康,在30秒沒收到心跳時將這個臨時實例摘除。插件

客戶端健康檢查和服務端健康檢查有一些不一樣的關注點。客戶端健康檢查主要關注客戶端上報心跳的方式、服務端摘除不健康客戶端的機制。而服務端健康檢查,則關注探測客戶端的方式、靈敏度及設置客戶端健康狀態的機制。從實現複雜性來講,服務端探測確定是要更加複雜的,由於須要服務端根據註冊服務配置的健康檢查方式,去執行相應的接口,判斷相應的返回結果,並作好重試機制和線程池的管理。這與客戶端探測,只須要等待心跳,而後刷新TTL是不同的。同時服務端健康檢查沒法摘除不健康實例,這意味着只要註冊過的服務實例,若是不調用接口主動註銷,這些服務實例都須要去維持健康檢查的探測任務,而客戶端則能夠隨時摘除不健康實例,減輕服務端的壓力。

 

5.性能與容量:

雖然大部分用戶用到的性能不高,可是他們仍然但願選用的產品的性能越高越好。影響讀寫性能的因素不少:一致性協議、機器的配置、集羣的規模、存量數據的規模、數據結構及讀寫邏輯的設計等等。在服務發現的場景中,咱們認爲讀寫性能都是很是關鍵的,可是並不是性能越高就越好,由於追求性能每每須要其餘方面作出犧牲。Zookeeper在寫性能上彷佛能達到上萬的TPS,這得益於Zookeeper精巧的設計,不過這顯然是由於有一系列的前提存在。首先Zookeeper的寫邏輯就是進行K-V的寫入,內部沒有聚合;其次Zookeeper捨棄了服務發現的基本功能如健康檢查、友好的查詢接口,它在支持這些功能的時候,顯然須要增長一些邏輯,甚至棄用現有的數據結構;最後,Paxos協議自己就限制了Zookeeper集羣的規模,三、5個節點是不能應對大規模的服務訂閱和查詢的。

 

6.易用性:

易用性也是用戶比較關注的一塊內容。產品雖然能夠在功能特性或者性能上作到很是先進,可是若是用戶的使用成本極高,也會讓用戶望而卻步。易用性包括多方面的工做,例如API和客戶端的接入是否簡單,文檔是否齊全易懂,控制檯界面是否完善等。對於開源產品來講,還有一塊是社區是否活躍。在比較Nacos、Eureka和Zookeeper在易用性上的表現時,咱們誠邀社區的用戶進行全方位的反饋,由於畢竟在阿里巴巴集團內部,咱們對Eureka、Zookeeper的使用場景是有限的。從咱們使用的經驗和調研來看,Zookeeper的易用性是比較差的,Zookeeper的客戶端使用比較複雜,沒有針對服務發現的模型設計以及相應的API封裝,須要依賴方本身處理。對多語言的支持也不太好,同時沒有比較好用的控制檯進行運維管理。

 

7.集羣擴展性:

集羣擴展性的另外一個方面是多地域部署和容災的支持。當講究集羣的高可用和穩定性以及網絡上的跨地域延遲要求可以在每一個地域都部署集羣的時候,咱們現有的方案有多機房容災、異地多活、多數據中心等。

首先是雙機房容災,基於Leader寫的協議不作改造是沒法支持的,這意味着Zookeeper不能在沒有人工干預的狀況下作到雙機房容災。在單機房斷網狀況下,使機房內服務可用並不難,難的是如何在斷網恢復後作數據聚合,Zookeeper的單點寫模式就會有斷網恢復後的數據對帳問題。Eureka的部署模式自然支持多機房容災,由於Eureka採用的是純臨時實例的註冊模式:不持久化、全部數據均可以經過客戶端心跳上報進行補償。上面說到,臨時實例和持久化實例都有它的應用場景,爲了可以兼容這兩種場景,Nacos支持兩種模式的部署,一種是和Eureka同樣的AP協議的部署,這種模式只支持臨時實例,能夠完美替代當前的Zookeeper、Eureka,並支持機房容災。另外一種是支持持久化實例的CP模式,這種狀況下不支持雙機房容災。

 

8.用戶擴展性:

在框架的設計中,擴展性是一個重要的設計原則。Spring、Dubbo、Ribbon等框架都在用戶擴展性上作了比較好的設計。這些框架的擴展性每每由面向接口及動態類加載等技術,來運行用戶擴展約定的接口,實現用戶自定義的邏輯。在Server的設計中,用戶擴展是比較審慎的。由於用戶擴展代碼的引入,可能會影響原有Server服務的可用性,同時若是出問題,排查的難度也是比較大的。設計良好的SPI是可能的,可是由此帶來的穩定性和運維的風險是須要仔細考慮的。在開源軟件中,每每經過直接貢獻代碼的方式來實現用戶擴展,好的擴展會被不少人不停的更新和維護,這也是一種比較好的開發模式。Zookeeper和Eureka目前Server端都不支持用戶擴展,一個支持用戶擴展的服務發現產品是CoreDNS。CoreDNS總體架構就是經過插件來串聯起來的,經過將插件代碼以約定的方式放到CoreDNS工程下,從新構建就能夠將插件添加到CoreDNS總體功能鏈路的一環中。

全部產品都應該儘可能支持用戶運行時擴展,這須要Server端SPI機制設計的足夠健壯和容錯。Nacos在這方面已經開放了對第三方CMDB的擴展支持,後續很快會開放健康檢查及負載均衡等核心功能的用戶擴展。目的就是爲了可以以一種解耦的方式支持用戶各類各樣的需求。

 

相關文章
相關標籤/搜索