天天看點

服務注冊發現consul之三:服務發現比較:Consul vs Zookeeper vs Etcd vs Eureka

這裡就平時經常用到的服務發現的産品進行下特性的對比,首先看下結論:

Feature

Consul

zookeeper

etcd

euerka

服務健康檢查

服務狀态,記憶體,硬碟等

(弱)長連接配接,keepalive

連接配接心跳

可配支援

多資料中心

支援

kv存儲服務

一緻性

raft

paxos

cap

cp

ap

使用接口(多語言能力)

支援http和dns

用戶端

http/grpc

http(sidecar)

watch支援

全量/支援long polling

支援 long polling

支援 long polling/大部分增量

自身監控

metrics

安全

acl /https

acl

https支援(弱)

spring cloud內建

已支援

Eureka是一個服務發現工具。該體系結構主要是用戶端/伺服器,每個資料中心有一組Eureka伺服器,通常每個可用區域一個。通常Eureka的客戶使用嵌入式SDK來注冊和發現服務。對于非本地內建的客戶,使用功能區邊框等透過Eureka透明地發現服務。

Eureka提供了一個弱一緻的服務視圖,使用盡力而為複制。當用戶端向伺服器注冊時,該伺服器将嘗試複制到其他伺服器,但不提供保證。服務注冊的生存時間(TTL)較短,要求用戶端對伺服器心存感激。不健康的服務或節點将停止心跳,導緻它們逾時并從系統資料庫中删除。發現請求可以路由到任何服務,由于盡力而為的複制,這些服務可能會導緻陳舊或丢失資料。這個簡化的模型允許簡單的群集管理和高可擴充性。

CONSUL提供了一套超級功能,包括更豐富的健康檢查,關鍵/價值存儲以及多資料中心意識。Consul需要每個資料中心都有一套伺服器,以及每個用戶端的代理,類似于使用像Ribbon這樣的負載均衡。Consul代理允許大多數應用程式成為Consul不知情者,通過配置檔案執行服務注冊并通過DNS或負載平衡器sidecars發現。

Consul提供強大的一緻性保證,因為伺服器使用Raft協定複制狀态 。Consul支援豐富的健康檢查,包括TCP,HTTP,Nagios / Sensu相容腳本或基于Eureka的TTL。用戶端節點參與基于Gossip的健康檢查,該檢查分發健康檢查工作,而不像集中式心跳檢測那樣成為可擴充性挑戰。發現請求被路由到選舉出來的領事上司,這使他們預設情況下強烈一緻。允許陳舊讀取的用戶端使任何伺服器都可以處理他們的請求,進而實作像Eureka這樣的線性可伸縮性。

Consul強烈的一緻性意味着它可以作為上司選舉和叢集協調的鎖定服務。Eureka不提供類似的保證,并且通常需要為需要執行協調或具有更強一緻性需求的服務運作ZooKeeper。

Consul提供了支援面向服務的體系結構所需的一系列功能。這包括服務發現,還包括豐富的運作狀況檢查,鎖定,密鑰/值,多資料中心聯合,事件系統和ACL。Consul和consul-template和envconsul等工具生态系統都試圖盡量減少內建所需的應用程式更改,以避免需要通過SDK進行本地內建。Eureka是一個更大的Netflix OSS套件的一部分,該套件預計應用程式相對均勻且緊密內建。是以,Eureka隻解決了一小部分問題,希望ZooKeeper等其他工具可以一起使用。

consul、zookeeper、etcd作為服務注冊中心的原理

後邊這兩個工具是通過鍵值存儲來實作服務的注冊與發現。

ZooKeeper利用臨時節點的機制,業務服務啟動時建立臨時節點,節點在服務就在,節點不存在服務就不存在。

etcd利用TTL機制,業務服務啟動時建立鍵值對,定時更新ttl,ttl過期則服務不可用。

ZooKeeper和etcd的鍵值存儲都是強一緻性的,也就是說鍵值對會自動同步到多個節點,隻要在某個節點上存在就可以認為對應的業務服務是可用的。

Consul的資料同步也是強一緻性的,服務的注冊資訊會在Server節點之間同步,相比ZK、etcd,服務的資訊還是持久化儲存的,即使服務部署不可用了,仍舊可以查詢到這個服務部署。但是業務服務的可用狀态是由注冊到的Agent來維護的,Agent如果不能正常工作了,則無法确定服務的真實狀态,并且Consul是相當穩定了,Agent挂掉的情況下大機率伺服器的狀态也可能是不好的,此時屏蔽掉此節點上的服務是合理的。Consul也确實是這樣設計的,DNS接口會自動屏蔽挂掉節點上的服務,HTTP API也認為挂掉節點上的服務不是passing的。

Apache Zookeeper -> CP

與 Eureka 有所不同,Apache Zookeeper

在設計時就緊遵CP原則,即任何時候對 Zookeeper 的通路請求能得到一緻的資料結果,同時系統對網絡分割具備容錯性,但是 Zookeeper

不能保證每次服務請求都是可達的。從 Zookeeper 的實際應用情況來看,在使用 Zookeeper 擷取服務清單時,如果此時的

Zookeeper 叢集中的 Leader 當機了,該叢集就要進行 Leader 的選舉,又或者 Zookeeper

叢集中半數以上伺服器節點不可用(例如有三個節點,如果節點一檢測到節點三挂了

,節點二也檢測到節點三挂了,那這個節點才算是真的挂了),那麼将無法處理該請求。是以說,Zookeeper 不能保證服務可用性。

當然,在大多數分布式環境中,尤其是涉及到資料存儲的場景,資料一緻性應該是首先被保證的,這也是

Zookeeper

設計緊遵CP原則的另一個原因。但是對于服務發現來說,情況就不太一樣了,針對同一個服務,即使注冊中心的不同節點儲存的服務提供者資訊不盡相同,也并不會造成災難性的後果。因為對于服務消費者來說,能消費才是最重要的,消費者雖然拿到可能不正确的服務執行個體資訊後嘗試消費一下,也要勝過因為無法擷取執行個體資訊而不去消費,導緻系統異常要好(淘寶的雙十一,京東的幺六八就是緊遵AP的最好參照)。

當master節點因為網絡故障與其他節點失去聯系時,剩餘節點會重新進行leader選舉。問題在于,選舉leader的時間太長,30~120s,而且選舉期間整個zk叢集都是不可用的,這就導緻在選舉期間注冊服務癱瘓。在雲部署環境下, 因為網絡問題使得zk叢集失去master節點是大機率事件,雖然服務能最終恢複,但是漫長的選舉事件導緻注冊長期不可用是不能容忍的。

Spring Cloud Eureka  -> AP

Spring Cloud Netflix 在設計 Eureka 時就緊遵AP原則(盡管現在2.0釋出了,但是由于其閉源的原因 ,但是目前 Ereka 1.x 任然是比較活躍的)。Eureka Server 也可以運作多個執行個體來建構叢集(後面專門的文章講解),解決單點問題,但不同于 ZooKeeper 的選舉 leader 的過程,Eureka Server 采用的是Peer to Peer 對等通信。這是一種去中心化的架構(參看:微服務與微服務架構思想與原則),無 master/slave 之分,每一個 Peer 都是對等的。在這種架構風格中,節點通過彼此互相注冊來提高可用性,每個節點需要添加一個或多個有效的 serviceUrl 指向其他節點。每個節點都可被視為其他節點的副本。

在叢集環境中如果某台 Eureka Server 當機,Eureka Client 的請求會自動切換到新的 Eureka Server 節點上,當當機的伺服器重新恢複後,Eureka 會再次将其納入到伺服器叢集管理之中。當節點開始接受用戶端請求時,所有的操作都會在節點間進行複制(replicate To Peer)操作,将請求複制到該 Eureka Server 目前所知的其它所有節點中。

當一個新的 Eureka Server 節點啟動後,會首先嘗試從鄰近節點擷取所有注冊清單資訊,并完成初始化。Eureka Server 通過 getEurekaServiceUrls() 方法擷取所有的節點,并且會通過心跳契約的方式定期更新。預設情況下,如果 Eureka Server 在一定時間内沒有接收到某個服務執行個體的心跳(預設周期為30秒),Eureka Server 将會登出該執行個體(預設為90秒,如果某個 eureka.instance.lease-expiration-duration-in-seconds 進行自定義配置)。當 Eureka Server 節點在短時間内丢失過多的心跳時,那麼這個節點就會進入自我保護模式(後面有文章會談及關于 Eureka Server 的自我保護機制)。

Eureka的叢集中,隻要有一台Eureka還在,就能保證注冊服務可用(保證可用性),隻不過查到的資訊可能不是最新的(不保證強一緻性)。除此之外,Eureka還有一種自我保護機制,如果在15分鐘内超過85%的節點都沒有正常的心跳,那麼Eureka就認為用戶端與注冊中心出現了網絡故障,此時會出現以下幾種情況:

Eureka不再從系統資料庫中移除因為長時間沒有收到心跳而過期的服務;

Eureka仍然能夠接受新服務注冊和查詢請求,但是不會被同步到其它節點上(即保證目前節點依然可用);

當網絡穩定時,目前執行個體新注冊的資訊會被同步到其它節點中;

是以,Eureka可以很好的應對因網絡故障導緻部分節點失去聯系的情況,而不會像zookeeper那樣使得整個注冊服務癱瘓。

在CAP中,Consul使用CP體系結構,有利于實作可用性的一緻性。

最大的差別是Eureka保證AP, Consul為CP。

Consul強一緻性(C)帶來的是:

服務注冊相比Eureka會稍慢一些。因為Consul的raft協定要求必須過半數的節點都寫入成功才認為注冊成功

Leader挂掉時,重新選舉期間整個consul不可用。保證了強一緻性但犧牲了可用性。

Eureka保證高可用(A)和最終一緻性:

服務注冊相對要快,因為不需要等注冊資訊replicate到其他節點,也不保證注冊資訊是否replicate成功

當資料出現不一緻時,雖然A, B上的注冊資訊不完全相同,但每個Eureka節點依然能夠正常對外提供服務,這會出現查詢服務資訊時如果請求A查不到,但請求B就能查到。如此保證了可用性但犧牲了一緻性。

其他方面,eureka就是個servlet程式,跑在servlet容器中; Consul則是go編寫而成。

Euraka 使用時需要顯式配置健康檢查支援;Zookeeper,Etcd 則在失去了和服務程序的連接配接情況下任務不健康,而 Consul 相對更為詳細點,比如記憶體是否已使用了90%,檔案系統的空間是不是快不足了。服務的健康檢查

多資料中心支援

    Consul 通過 WAN 的 Gossip 協定,完成跨資料中心的同步;而且其他的産品則需要額外的開發工作來實作;

KV 存儲服務

    除了 Eureka ,其他幾款都能夠對外支援 k-v 的存儲服務,是以後面會講到這幾款産品追求高一緻性的重要原因。而提供存儲服務,也能夠較好的轉化為動态配置服務哦。

産品設計中 CAP 理論的取舍

    Eureka 典型的 AP,作為分布式場景下的服務發現的産品較為合适,服務發現場景的可用性優先級較高,一緻性并不是特别緻命。其次 CP 類型的場景 Consul,也能提供較高的可用性,并能 k-v store 服務保證一緻性。 而Zookeeper,Etcd則是CP類型 犧牲可用性,在服務發現場景并沒太大優勢;

多語言能力與對外提供服務的接入協定

    Zookeeper的跨語言支援較弱,其他幾款支援 http11 提供接入的可能。Euraka 一般通過 sidecar的方式提供多語言用戶端的接入支援。Etcd 還提供了Grpc的支援。 Consul除了标準的Rest服務api,還提供了DNS的支援。

Watch的支援(用戶端觀察到服務提供者變化)

    Zookeeper 支援伺服器端推送變化,Eureka 2.0(正在開發中)也計劃支援。 Eureka 1,Consul,Etcd則都通過長輪詢的方式來實作變化的感覺;

自身叢集的監控

    除了 Zookeeper ,其他幾款都預設支援 metrics,運維者可以搜集并報警這些度量資訊達到監控目的;

    Consul,Zookeeper 支援ACL,另外 Consul,Etcd 支援安全通道https.

Spring Cloud的內建

    目前都有相對應的 boot starter,提供了內建能力。

總的來看,目前Consul 自身功能,和 spring cloud 對其內建的支援都相對較為完善,而且運維的複雜度較為簡單(沒有詳細列出讨論),Eureka 設計上比較符合場景,但還需持續的完善。

繼續閱讀