服務發現的基本原理與比較:Eureka vs Consul vs Zookeeper

專注於Java領域優質技術號,歡迎關注

前言

在雲計算和容器化技術發展火熱的當下,對於微服務架構,服務註冊與發現組件是必不可少的。在傳統的服務架構中,服務的規模處於運維人員的可控範圍內。當部署服務的多個節點時,一般使用靜態配置的方式實現服務信息的設定。在微服務應用中,服務實例的數量和網絡地址都是動態變化的,這對系統運維提出了巨大的挑戰。因此,動態的服務註冊與發現就顯得尤為重要。

解決的問題

在一個分佈式系統中,服務註冊與發現組件主要解決兩個問題:服務註冊和服務發現。

  • 服務註冊:服務實例將自身服務信息註冊到註冊中心。這部分服務信息包括服務所在主機IP和提供服務的Port,以及暴露服務自身狀態以及訪問協議等信息。
  • 服務發現:服務實例請求註冊中心獲取所依賴服務信息。服務實例通過註冊中心,獲取到註冊到其中的服務實例的信息,通過這些信息去請求它們提供的服務。

除此之外,服務註冊與發現需要關注監控服務實例運行狀態、負載均衡等問題。

  • 監控:微服務應用中,服務處於動態變化的情況,需要一定機制處理無效的服務實例。一般來講,服務實例與註冊中心在註冊後通過心跳的方式維繫聯繫,一旦心跳缺少,對應的服務實例會被註冊中心剔除。
  • 負載均衡:同一服務可能同時存在多個實例,需要正確處理對該服務的負載均衡。

CAP

CAP原則,指的是在一個分佈式系統中,Consistency(一致性)、Availability(可用性)、Partition Tolerance(分區容錯性),不能同時成立。

  • 一致性:它要求在同一時刻點,分佈式系統中的所有數據備份都處於同一狀態。
  • 可用性:在系統集群的一部分節點宕機後,系統依然能夠響應用戶的請求。
  • 分區容錯性:在網絡區間通信出現失敗,系統能夠容忍。

一般來講,基於網絡的不穩定性,分佈容錯是不可避免的,所以我們默認CAP中的P總是成立的。

一致性的強制數據統一要求,必然會導致在更新數據時部分節點處於被鎖定狀態,此時不可對外提供服務,影響了服務的可用性,反之亦然。因此一致性和可用性不能同時滿足。

我們接下來介紹的服務註冊和發現組件中,Eureka滿足了其中的AP,Consul和Zookeeper滿足了其中的CP。

Eureka

Eureka是在Java語言上,基於Restful Api開發的服務註冊與發現組件,由Netflix開源。遺憾的是,目前Eureka僅開源到1.X版本,2.X版本已經宣佈閉源。

Eureka採用的是Server/Client的模式進行設計。Server扮演了服務註冊中心的角色,為Client提供服務註冊和發現的功能,維護著註冊到自身的Client的相關信息,同時提供接口給Client獲取到註冊表中其他服務的信息。Client將有關自己的服務的信息通過一定的方式登記到Server上,並在正常範圍內維護自己信息的一致性,方便其他服務發現自己,同時可以通過Server獲取到自己的依賴的其他服務信息,從而完成服務調用。

它的架構圖如下所示:

服務發現的基本原理與比較:Eureka vs Consul vs Zookeeper

eureka-architecture

  • Application Service: 作為Eureka Client,扮演了服務的提供者,提供業務服務,向Eureka Server註冊和更新自己的信息,同時能從Eureka Server的註冊表中獲取到其他服務的信息。
  • Eureka Server:扮演服務註冊中心的角色,提供服務註冊和發現的功能,每個Eureka Cient向Eureka Server註冊自己的信息,也可以通過Eureka Server獲取到其他服務的信息達到發現和調用其他服務的目的。
  • Application Client:作為Eureka Client,扮演了服務消費者,通過Eureka Server獲取到註冊到上面的其他服務的信息,從而根據信息找到所需的服務發起遠程調用。
  • Replicate: Eureka Server中的註冊表信息的同步拷貝,保持不同的Eureka Server集群中的註冊表中的服務實例信息的一致性。提供了數據的最終一致性。
  • Make Remote Call: 服務之間的遠程調用。
  • Register: 註冊服務實例,Client端向Server端註冊自身的元數據以進行服務發現。
  • Renew:續約,通過發送心跳到Server維持和更新註冊表中的服務實例元數據的有效性。當在一定時長內Server沒有收到Client的心跳信息,將默認服務下線,將服務實例的信息從註冊表中刪除。
  • Cancel:服務下線,Client在關閉時主動向Server註銷服務實例元數據,這時Client的的服務實例數據將從Server的註冊表中刪除。

Eureka中沒有使用任何的數據強一致性算法保證不同集群間的Server的數據一致,僅通過數據拷貝的方式爭取註冊中心數據的最終一致性,雖然放棄數據強一致性但是換來了Server的可用性,降低了註冊的代價,提高了集群運行的健壯性。

Consul

Consul是由HashiCorp基於Go語言開發的支持多數據中心分佈式高可用的服務發佈和註冊服務軟件,採用Raft算法保證服務的一致性,且支持健康檢查。

Consul採用主從模式的設計,使得集群的數量可以大規模擴展,集群間通過RPC的方式調用(HTTP和DNS)。它的結構圖如下所示:

服務發現的基本原理與比較:Eureka vs Consul vs Zookeeper

consul-architecture

  • Client:作為一個代理(非微服務實例),它將轉發所有的RPC請求到Server中。作為相對無狀態的服務,它不持有任何註冊信息。
  • Server:作為一個具備擴展功能的代理,它將響應RPC查詢、參與Raft選舉、維護集群狀態和轉發查詢給Leader等。
  • Leader-Server:一個數據中心的所有Server都作為Raft節點集合的一部分。其中Leader將負責所有的查詢和事務(如服務註冊),同時這些事務也會被複制到所有其他的節點。
  • Data Center:數據中心作為一個私有的,低延遲和高帶寬的一個網絡環境。每個數據中心會存在Consul集群,一般建議Server是3-5臺(考慮到Raft算法在可用性和性能上取捨),而Leader只能唯一,Client的數量沒有限制,可以輕鬆擴展。

Raft算法

Raft算法將Server分為三種類型:Leader、Follower和Candidate。Leader處理所有的查詢和事務,並向Follower同步事務。Follower會將所有的RPC查詢和事務轉發給Leader處理,它僅從Leader接受事務的同步。數據的一致性以Leader中的數據為準實現。

在節點初始啟動時,節點的Raft狀態機將處於Follower狀態等待來來自Leader節點的心跳。如果在一定時間週期內沒有收到Leader節點的心跳,節點將發起選舉。

Follower節點選舉時會將自己的狀態切換為Candidate,然後向集群中其它Follower節點發送請求,詢問其是否選舉自己成為Leader。當收到來自集群中過半數節點的接受投票後,節點即成為Leader,開始接收Client的事務處理和查詢並向其它的Follower節點同步事務。Leader節點會定時向Follower發送心跳來保持其地位。

Gossip協議

Gossip協議是為了解決分佈式環境下監控和事件通知的瓶頸。Gossip協議中的每個Agent會利用Gossip協議互相檢查在線狀態,分擔了服務器節點的心跳壓力,通過Gossip廣播的方式發送消息。

所有的Agent都運行著Gossip協議。服務器節點和普通Agent都會加入這個Gossip集群,收發Gossip消息。每隔一段時間,每個節點都會隨機選擇幾個節點發送Gossip消息,其他節點會再次隨機選擇其他幾個節點接力發送消息。這樣一段時間過後,整個集群都能收到這條消息。

基於Raft算法,Consul提供強一致性的註冊中心服務,但是由於Leader節點承擔了所有的處理工作,勢必加大了註冊和發現的代價,降低了服務的可用性。通過Gossip協議,Consul可以很好地監控Consul集群的運行,同時可以方便通知各類事件,如Leader選擇發生、Server地址變更等。

Zookeeper

Zookeeper是由Google開源的在Java語言上實現的分佈式協調服務,是Hadoop和Hbase的重要組件,提供了數據/發佈訂閱、負載均衡、分佈式同步等功能。

Zookeeper也是基於主從架構,搭建了一個可高擴展的服務集群,其服務架構如下:

服務發現的基本原理與比較:Eureka vs Consul vs Zookeeper

zookeeper-architecture

  • Leader-Server:Leader負責進行投票的發起和決議,更新系統中的數據狀態
  • Server:Server中存在兩種類型:Follower和Observer。其中Follower接受客戶端的請求並返回結果(事務請求將轉發給Leader處理),並在選舉過程中參與投票;Observer與Follower功能一致,但是不參與投票過程,它的存在是為了提高系統的讀取速度
  • Client:請求發起方,Server和Client之間可以通過長連接的方式進行交互。如發起註冊或者請求集群信息等。

Zab協議

ZooKeeper Atomic Broadcast protocol是專門設計給Zookeeper用於實現分佈式系統數據的一致性,是在Paxos算法基礎上發展而來。它使用了單一的Leader來接受和處理客戶端的所有事務請求,並將服務器數據的狀態變更以事務Proposal的形式廣播到所有的Server中。同時它保證Leader出現異常時,集群依舊能夠正常工作。Zab包含兩種基本模式:崩潰恢復和消息廣播。

  • 崩潰恢復:Leader服務器出現宕機,或者因為網絡原因導致Leader服務器失去了與過半 Follower的聯繫,那麼就會進入崩潰恢復模式從而選舉新的Leader。Leader選舉算法不僅僅需要讓Leader自己知道其自身已經被選舉為Leader,同時還需要讓集群中的所有其他服務器也能夠快速地感知到選舉產生的新的Leader。當選舉產生了新的Leader,同時集群中有過半的服務器與該Leader完成了狀態同步之後,Zab協議就會退出崩潰恢復模式,進入消息廣播模式。
  • 消息廣播:Zab協議的消息廣播過程類似二階段提供過程,是一種原子廣播的協議。當接受到來自Client的事務請求(如服務註冊)(所有的事務請求都會轉發給Leader),Leader會為事務生成對應的Proposal,併為其分配一個全局唯一的ZXID。Leader服務器與每個Follower之間都有一個單獨的隊列進行收發消息,Leader將生成的Proposal發送到隊列中。Follower從隊列中取出Proposal進行事務消費,消費完畢後發送一個ACK給Leader。當Leader接受到半數以上的Follower發送的ACK投票,它將發送Commit給所有Follower通知其對事務進行提交,Leader本身也會提交事務,並返回給處理成功給對應的客戶端。Follower只有將隊列中Proposal都同步消費後才可用。

基於Zab協議,Zookeeper可以用於構建具備數據強一致性的服務註冊與發現中心,而與此相對地犧牲了服務的可用性和提高了註冊需要的時間。

異同點

最後我們通過一張表格大致瞭解Eureka、Consul、Zookeeper的異同點。選擇什麼類型的服務註冊與發現組件可以根據自身項目要求決定。

服務發現的基本原理與比較:Eureka vs Consul vs Zookeeper

鏈接:https://www.jianshu.com/p/086f8066188b


分享到:


相關文章: