1. 程式人生 > >服務發現的基本原理與比較:Eureka vs Consul vs Zookeeper

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

前言

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

解決的問題

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

  • 服務註冊:服務例項將自身服務資訊註冊到註冊中心。這部分服務資訊包括服務所在主機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獲取到自己的依賴的其他服務資訊,從而完成服務呼叫。

它的架構圖如下所示:
在這裡插入圖片描述

  • 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)。它的結構圖如下所示:
在這裡插入圖片描述

  • 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也是基於主從架構,搭建了一個可高擴充套件的服務叢集,其服務架構如下:
在這裡插入圖片描述

  • 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的異同點。選擇什麼型別的服務註冊與發現元件可以根據自身專案要求決定。

元件名 語言 CAP 一致性演算法 服務健康檢查 對外暴露介面 Spring Cloud整合
Eureka Java AP 可配支援 HTTP 已整合
Consul Go CP Raft 支援 HTTP/DNS 已整合
Zookeeper Java CP Paxos 支援 客戶端 已整合