在實際的項目選型中,該如何考慮選擇合适的注冊中心呢?我在網上找了很多資料,但都基本不是最新的,比如說幾乎所有的資料都還在說隻有Eureka支援Spring Cloud的內建,其他注冊中心均不支援Spring Cloud。是以,就想要自己寫一篇最新最全的注冊中心的特點比較的文章,來幫助自己以及親愛的粉絲們重新梳理他們的特點,以保證以更全方位的考慮來進行項目選型
序号 | 比較項 | Eureka | zookeeper | Nacos | Consul |
1 | 叢集結構 | 平級 | 主從 | 支援平級和主從 | |
2 | 叢集角色 | 主人 | Leader、follower observer | leader、follower、candidate | server-leader、server以及client |
3 | 是否可以及時知道服務狀态變化 | 不能及時知道 | 會及時知道 | ||
4 | 一緻性協定(CAP) | 注重可用性(AP) | 注重一緻性(CP) | 支援CP和AP-如何實作 | |
5 | 雪崩保護 | 有 | 沒有 | ||
6 | 社群是否活躍 | Eureka2.0不再維護了 | 持續維護 | ||
7 | 管理端 | 有現成的eureka管理端 | 沒有現成的管理端 | 有現成的管理端 | |
8 | 負載均衡政策 | 使用ribbon實作 | 一般可以直接采用RPC的負載均衡 | 權重/metadata/Selector | Fabio |
9 | 權限控制 | 無 | 使用ACL實作節點權限控制 | RBAC-使用者、角色、權限 | ACL |
10 | Spring Cloud內建 | 支援 | |||
11 | 健康檢查 | Client Beat | Keep Alive | TCP/HTTP/MYSQL/Client Beat | TCP/HTTP/gRPC/Cmd |
12 | 自動登出執行個體 | 不支援 | |||
13 | 通路協定 | HTTP | TCP | HTTP/DNS | |
14 | 是否可用作配置中心 | 否 | 是 | ||
15 | 多資料中心 | ||||
16 | 跨注冊中心同步 | ||||
17 | Dubbo內建 | ||||
18 | K8S內建 |
1 叢集結構 Eureka的叢集架構本身就是平級結構zookeeper和consul則均為主從結構Nacos則支援平級關系和主從這兩種叢集架構,常用的是後者
具體架構是怎樣的,可以繼續往下看~2 叢集角色 我發現,叢集架構和角色往往是一個注冊中心的核心功能,搞清楚這兩點,基本上對于這個注冊中心已經掌握了一半了。來分别看看四個注冊中心的叢集角色吧~1)Eureka:叢集各節點都是平起平坐的關系,資料是互相複制的,是以各個節點都是主人角色
如圖,服務端Eureka-server會存儲服務執行個體資訊,通過複制實作服務執行個體資訊在各個節點同步,并定期去檢查服務執行個體資訊狀态;各個用戶端也會通過健康檢查等機制進行自我狀态檢查,要是資訊有了變化,均會向服務Eureka-server發起請求Eureka-server則會分别處理這些狀态變化,來保持執行個體資訊的更新2)zookeeper:叢集角色包含leader、follower以及observer三類
具體來說是一主多從結構,就是有一個leader,多個follower,以及隻負責讀操作、不參與選舉的observer
下面是關于三個角色之間的關系圖
a)首先圖上是有client和server兩大角色。client通過TCP與其中一個server建立連接配接。其中server分為leader、follower,以及observer三個角色
leader:負責投票的發起和決議
follower:同步leader的狀态,參與leader選舉。将寫操作轉發給leader,并參與“過半寫成功”政策
observer:同步leader的狀态,将寫操作轉發給Leader。不參加投票選舉過程,也不參加寫操作的“過半寫成功”政策
b)當leader因為網絡或者其他原因挂掉之後,會重新在follower裡面選擇一個新的leader。
c)observer 機器可以在不影響寫性能的情況下提升叢集的讀性能。
3)cosul:叢集角色包含server-leader、server以及client 這三個角色實際上可以分别對應zookeeper中的leader,follower以及observer。對了,這塊第三種角色-client,千萬要注意,它還是屬于consul的服務端的一個節點角色,而不是consul的用戶端哦來,看一下這張圖,來梳理一下他們各自的功能
client : consul的client模式的節點。接收到consul的用戶端請求以後,不做處理,會轉發到server-leader,也不會持久化資訊server: consul的server模式的節點,功能和client都一樣。唯一不同的是,它會把所有的資訊持久化到本地,這樣遇到故障,資訊是可以被保留的server-leader: 名字就已經說明,這個server是所有服務端接節點的老大了,那麼它自然負責的工作就多啦~ 它除了和普通的server模式的節點一樣,需要進行資訊持久化以外,還額外需要負責同步注冊的資訊給其它的server,同時也要負責各個節點的健康監測4)Nacos:包含leader、follower、candidate三類Leader:負責Client互動和log複制,同一時刻系統中最多存在1個Follower:被動響應請求RPC,從不主動發起請求RPC。接收到請求,會轉發給leader處理Candidate:一種臨時的角色,隻存在于leader的選舉階段某個節點想要變成leader,那麼就發起投票請求,同時自己變成candidate,如果選舉成功,則變為candidate,否則退回為follower具體流程如下圖所示:
a 叢集啟動後,初始節點狀态都是 Follower 狀态b 某個follower想要被選舉成為leader,于是變成candidate(候選人)狀态,向自己投票,并向其他follower發起投票請求c 收到其他節點的投票響應以後,若超過半數的follower都投了自己,則投票成功,自己的狀态變為leaderd 如果并沒有收到大多數的選票,則進行新一輪的投票3 是否可以及時知道服務狀态變化由于zooKeeper具有watcher機制,是以可以及時知道資料目錄的狀态變化,那麼也就可以及時知道伺服器節點以及所注冊的執行個體的變化。我們可以通過這種監聽機制,能夠實時擷取到某個伺服器的故障或者我們比較關心的節點資料的更改(zookeeper的節點znode包含伺服器節點和資料節點)其他三個注冊中心沒有這樣的機制,隻是可以通過管理端進行主動檢視服務狀态,并不能實時感覺服務狀态的變化4 一緻性協定(CAP) 首先,我們再複習一下CAP原理(參考維基百科)在理論計算機科學中,CAP定理,又被稱作布魯爾定理,它指出對于一個分布式計算系統來說,不可能同時滿足以下三點:1)一緻性(Consistency)注冊中心的叢集各個節點的資料資訊完全一緻2)可用性(Availability)每次請求都能擷取到非錯的響應——但是不保證擷取的資料為最新資料3)分區容錯性(Partition tolerance)以實際效果而言,分區相當于對通信的時限要求。系統如果不能在時限内達成資料一緻性,就意味着發生了分區的情況,必須就目前操作在C和A之間做出選擇根據定理,分布式系統隻能滿足三項中的兩項,而不可能滿足全部三項了解CAP理論的最簡單方式是想象兩個節點分處分區兩側。允許至少一個節點更新狀态會導緻資料不一緻,即喪失了C性質。如果為了保證資料一緻性,将分區一側的節點設定為不可用,那麼又喪失了A性質。除非兩個節點可以互相通信,才能既保證C又保證A,這又會導緻喪失P性質而四個注冊中心,對一緻性協定的支援情況如下: Eureka :支援AP,即保障可用性和分區容錯性
Zookeeper:支援CP,即保障一緻性和分區容錯性consul:支援CP,即保障一緻性和分區容錯性nacos:支援AP和CP兩種模式。可以分别支援AP和CP兩種場景 C是所有節點在同一時間看到的資料是一緻的;A是所有的請求都會收到響應。一個保證一緻性,一個保證可用性。那麼,對于Nacos,如何選擇使用哪種模式呢? 1)一般來說,如果不需要存儲服務級别的資訊,且服務執行個體是通過Nacos-client注冊,并能夠保持心跳上報,那麼就可以選擇AP模式。AP模式為了服務的可用性而減弱了一緻性,是以AP模式下隻能注冊臨時執行個體 2)如果需要在服務級别編輯或存儲配置資訊,那麼CP是必須,K8S服務和DNS服務則适用于CP服務,CP模式下則支援注冊持久化執行個體,此時則是以Raft協定為叢集運作模式,該模式下注冊執行個體之前必須先注冊服務,如果服務不存在,則會傳回錯誤那麼該如何切換這兩種模式呢?1)執行如下指令:curl -X PUT `$NACOS_SERVER:8848/nacos/v1/ns/operator/switches?entry=serverMode&value=CP'
2)同時微服務的bootstrap.properties 需配置如下選項指明注冊為臨時/永久執行個體
#false-注冊永久執行個體,true-注冊為臨時執行個體
spring.cloud.nacos.discovery.ephemeral=false
5 自動登出執行個體除了consul不支援自動登出執行個體以外,其他三個注冊中心均支援自動登出執行個體1)Eureka:預設情況下,如果Eureka Server在90秒内沒有接收到某個微服務執行個體的心跳,Eureka Server将會登出該執行個體(時間間隔可以配置)2)zookeeper:使用臨時節點,依托于Session逾時時間來實作TTL功能來實作自動登出。可以給每一個鍵或目錄指定一個存活時限TTL,當指定的秒數過去以後,如果相應的鍵或目錄沒有得到更新,就會被自動從Etcd記錄中移除3)Nacos:從 0.5.0 版本開始,使用者通過用戶端SDK注冊的執行個體,将預設開啟TTL功能,執行個體會預設每5秒向服務端發送一次心跳,如果Nacos服務端15秒内沒有收到執行個體的心跳,則會将執行個體置為不健康,如果30秒沒有收到心跳,則會将直接将執行個體删除Tips:TTL,是Time To Live的簡稱,意思為一條域名解析記錄在DNS伺服器中的存留時間6 雪崩保護1)Eureka :有雪崩保護。我們知道,當網絡分區故障發生時,微服務與Eureka Server之間突然無法正常通信了,根據心跳機制,微服務将會被登出。那麼這種心跳機制是不是就變得不太友好了?因為這種情況下微服務本身其實是健康的,本不應該登出這個微服務,是以Eureka就提供了一個自我保護機制,也就是雪崩保護機制;a)條件:當Eureka Server節點在短時間内丢失過多用戶端(可能發生了網絡分區故障),預設是15分鐘内收到的續約低于原來的85%時,這個節點就會進入自我保護模式b)動作:一旦進入該模式,Eureka Server仍能接收新服務的注冊和查詢請求,但是不會同步到其他節點上;同時也會保護服務系統資料庫中的資訊,不再移除注冊清單中因為長時間沒收到心跳而應該過期的服務。當網絡故障恢複後,該Eureka Server節點會自動退出自我保護模式這樣擷取的資料的确有可能不是最新的,但Eureka的這種自我保護機制,極大地保證了Eureka的高可用特性2)Zookeeper:沒有雪崩保護3)consul:沒有雪崩保護4)nacos:有雪崩保護。為了防止因過多執行個體 (Instance) 不健康導緻流量全部流向健康執行個體 (Instance) ,繼而造成流量壓力把健康執行個體 (Instance) 壓垮并形成雪崩效應,應将健康保護門檻值定義為一個 0 到 1 之間的浮點數當域名健康執行個體占總服務執行個體的比例小于該值時,無論執行個體是否健康,都會将這個執行個體傳回給用戶端。這樣做雖然損失了一部分流量,但是保證了叢集的剩餘健康執行個體 (Instance) 能正常工作7 社群是否活躍Eureka2.0不再維護了,而其他三個注冊中心依舊在持續維護中,其中Nacos和Consul的社群應該說活躍度是最高的。從代碼更新速度來講,也是如此。分别看了一下eureka、zookeeper、nacos以及consul的代碼更新記錄1)eureka
2)zookeeper
3)nacos
4)consul
會發現,Eureka的更新頻率相對來說,明顯比較低,Zookeeper逐漸趨于成熟化,是以代碼更新頻率也很低,隻是稍好于Eureka。而Nacos和Consul的更新頻率明顯很高,是以社群活躍度來說,Nacos和Consul還是很有優勢的,是以對于未來的微服務項目的注冊中心選型,更建議考慮這兩種,更有保障一些8 是否有管理端Eureka、Consul和Nacos都有現成的管理端zookeeper沒有現成的管理端,但用戶端也可以根據提供的API,很容易自己實作一個也控制台,比如zkui就是其中一個比較好用的zookeeper管理端9 負載均衡政策Eureka:使用ribbon實作Zookeeper:一般可以直接采用RPC的負載均衡Nacos:采用權重/metadata/SelectorConsul:使用Fabio關于負載均衡政策,這塊就不做過多介紹了,感興趣的可以在網上找找~10 權限控制Eureka本身沒有權限控制的機制,是以它需要與Spring Cloud Security來實作它的權限控制;zookeeper:使用ACL實作節點權限控制nacos:使用RBAC實作節點權限控制-使用者、角色、權限consul:使用ACL實作節點權限控制11 Spring Cloud內建四個注冊中心,現均已支援Spring Cloud的內建12 健康檢查Eureka:Eureka Server 與 Eureka Client 之間使用心跳機制來确定Eureka Client 的狀态,預設情況下,伺服器端與用戶端的心跳保持正常,應用程式就會始終保持UP狀态
Zookeeper:本身沒有健康檢查機制,需要消費者自己實作服務提供者的健康檢查動作Nacos:Nacos 支援傳輸層(PIND 或 TCP)和應用層(如 HTTP、MySQL以及使用者自定義)的監控檢查,同時還支援類似于Eureka的心跳機制的健康檢查Consul:TCP/HTTP/gRPC/Cmd健康檢查,不得不說,是Consul的一個亮點特性了!Consul支援以下幾種類型的健康檢查:1)腳本檢查機制:通過執行程式外的腳本2)HTTP檢查機制:通過向指定的URL發起GET請求,服務的狀态依賴HTTP請求的狀态碼:2xx - passing429 - Too ManyRequests is a warningother - failure與使用Curl或是外部程序檢查的健康檢查機制相比,HTTP檢查機制應該是首選的3)TCP檢查機制通過與指定的IP/hostname + 端口監理TCP連接配接4)TTL檢查機制保留了給定的TTL(生命周期)的最新的狀态,這些狀态必須通過HTTP接口定時進行更新,需要服務周期性彙報健康狀态5)Docker檢查機制 依賴觸發一同被打包進容器的外部應用程式13 通路協定Eureka采用HTTP協定進行通路Zookeeper采用TCP進行通路而Nacos和Consul除了支援HTTP協定通路以外,還支援DNS協定14 是否可用作配置中心除了eureka不可以作為配置中心以外,其他三個注冊中心均可以作為配置中心15 多資料中心隻有consul支援多資料中心,但其他注冊中心都有方案部署為多資料中心16 跨注冊中心同步nacos和consul支援跨注冊中心同步17 Dubbo內建zookeeper和Nacos支援Dubbo內建,Eureka和consul則暫不支援18 K8S內建四個注冊中心均支援k8s內建
好了,今天呢,我們主要通過18個方面,對四個注冊中心做了分析比較,重新梳理比較了4個注冊中心的核心特點。總得來說,四個注冊中心各有優勢consul和新晉的nacos的社群活躍度比較高,nacos可以同時支援AP和CP;consul則結合了zookeeper和nacos的諸多優點,還天然支援多資料中心;而zookeeper則又可以唯一感覺到服務狀态的實時變化;Eureka的自我保護機制使得它即使隻剩下一台服務,也不影響正常運作,具有高可用性那麼選擇的時候,究竟應該如何選擇呢?需要結合業務場景來進行選擇。比如說,對于金融類的業務場景,對于一緻性要求更高,那麼就會排除掉Eureka,然後根據易用性、成本效益等其他方面再進行後續的選擇;對于高可用比較注重的項目,如電商類項目,則可以選擇Eurek或者Nacos,但再比較其他方面,Nacos不僅可以做注冊中心,還可以作為架構中的配置中心,并且社群活躍度比較高,功能也日漸在完善,使用的人越來越多,是以綜合來講,就選擇了Nacos具體選擇的過程中,當然也會考慮這些因素之外的一些特點,包括人員的熟悉度等等,但肯定也是先考慮主要的特點,再去考慮這些不是那麼重要的特點