天天看點

【華為雲專家原創】 服務注冊與發現如何滿足服務治理?

摘要:本文主要介紹了服務注冊與發現的原理,以及常用的幾種服務注冊與發現元件介紹對比。

在單體應用向微服務架構演進的過程中,原本的巨石型應用會按照業務需求被拆分成多個微服務,每個服務提供特定的功能,并可能依賴于其他的微服務。每個微服務執行個體都可以動态部署,服務執行個體之間的調用通過輕量級的遠端調用方式(HTTP、消息隊列等)實作,它們之間通過預先定義好的接口進行通路。

由于服務執行個體是動态部署,每個服務執行個體的位址和服務資訊都可能動态變化,勢必需要一個中心化的元件對各個服務執行個體的資訊進行管理,該元件管理了各個部署好的服務執行個體中繼資料,包括不僅限于服務名、IP 位址、端口号、服務描述和服務狀态等。

什麼是服務注冊與發現?

服務注冊與發現主要包含兩部分:服務注冊與服務發現。服務注冊是指服務執行個體啟動時将自身資訊注冊到服務注冊與發現中心,并在運作時通過心跳等方式向服務注冊與發現中心彙報自身服務狀态;服務發現是指服務執行個體向服務注冊與發現中心擷取其他服務執行個體資訊,用于進行接下來的遠端調用。接下來讓我們介紹服務注冊與發現中心的職責和服務執行個體進行服務注冊的基本流程,以及分布式系統中資料同步的基本原理 CAP。

服務注冊與發現中心有什麼功能?

在傳統單體應用中,應用都是部署在固定的實體機器或者雲平台上,他們之間的調用一般是通過固定在代碼内部或者配置檔案的服務位址和端口直接發起。由于應用數量較少,系統結構複雜度不高,開發人員和運維人員可以較為輕松地進行管理和配置。

随着應用架構向微服務架構遷移,服務數量的增加和動态部署動态擴充的特性,使得服務位址和端口在運作時是随時可變的。對此,我們需要一個額外的中心化元件統一管理動态部署的微服務應用的服務執行個體中繼資料,一般稱它為服務注冊與發現中心。服務注冊與發現中心主要有以下的職責:

  • 管理目前注冊到服務注冊與發現中心的微服務執行個體中繼資料資訊,包括服務執行個體的 服務名、IP 位址、端口号、服務描述和服務狀态等;
  • 與注冊到服務發現與注冊中心的微服務執行個體維持心跳,定期檢查系統資料庫中的服務執行個體是否線上,并剔除無效服務執行個體資訊;
  • 提供服務發現能力,為服務調用方提供服務提供方的服務執行個體中繼資料。

通過服務發現與注冊中心,可以很友善地管理系統中動态變化的服務執行個體資訊。與此同時,它也可能成為系統的瓶頸和故障點。因為服務之間的調用資訊來自于服務注冊與發現中心,當它不可用時,服務之間的調用可能無法正常進行。是以服務發現與注冊中心一般會叢集化部署,提供高可用性和高穩定性。

分布式中的 CAP 理論

在本質上來講,微服務應用屬于分布式系統的一種落地實踐,而分布式系統最大的難點是處理各個節點之間資料狀态的一緻性。即使是倡導無狀态的 HTTP RESTful API 請求,在處理多服務執行個體情況下的修改資料狀态請求,也是需要通過資料庫或者分布式緩存等外部系統維護資料的一緻性。CAP 原理是描述分布式系統下節點資料同步的基本定理。

CAP 原理由加州大學的 Eric Brewer 教授提出,分别指 Consistency (一緻性)、Availablity (可用性)、Partition tolerance (分區容忍性)。Eric Brewer 認為,以上三個名額最多同時滿足兩個。

  • Consistency,指資料一緻性,表示一個系統的資料資訊(包括備份資料)在同一時刻都是一緻的。在分布式系統下,同一份資料可能存在于多個不同的執行個體中,在資料強一緻性的要求下,對其中一份資料的修改必須同步到它的所有備份中。在資料同步的任何時候,都需要保證所有對該份資料的請求将傳回同樣的狀态。
  • Availablity,指服務可用性,要求服務在接受到用戶端請求後,都能夠給出響應。服務可用性考量的是系統的可用性,要求系統在高并發情況下和部分節點當機的情況下,系統整體依然能夠響應用戶端的請求。
  • Partition tolerance,指分區容忍性。在分布式系統中,不同節點之間是通過網絡進行通信。基于網絡的不可靠性,位于不同網絡分區的服務節點可能會通信失敗,如果系統能夠容忍這種情況,說明它是滿足分區容忍性的。如果系統不能夠滿足分區容忍性,那麼将會限制分布式系統的擴充性,即服務節點的部署數量和地區都會受限,違背了分布式系統設計的初衷,是以一般來講分布式系統都會滿足分區容忍性。

在滿足了分區容忍性的前提下,分布式系統并不能同時滿足資料一緻性和服務可用性。假設服務A現在有兩個執行個體A1和A2,它們之間的網絡通信出現了異常,基于分區容忍性,這并不會影響A1和A2獨立的正常運作。假如此時用戶端請求A1,請求将資料B從B1狀态修改為B2,由于網絡的不可用,資料B的修改并不能通知到執行個體A2。如果此時另一個用戶端向A2請求資料B,如果A2傳回資料B1,将滿足服務可用性,但并不能滿足資料一緻性;如果A2需要等待A1的通知之後才能夠傳回資料B的正确狀态,雖然滿足了資料一緻性,但并不能響應用戶端請求,違背了服務可用性的名額。

基于分布式系統的基本特質,P 是必須要滿足,接下來需要考慮滿足 C 還是 A。在類似銀行之類對金額資料要求強一緻性的系統中,要優先考慮滿足資料一緻性;而類似大衆網頁之類的系統,使用者對網頁版本的新舊不會有特别的要求,在這種場景下服務可用性高于資料一緻性。

如何選擇服務注冊與發現架構?

随着近幾年微服務架構高速發展,目前業界已經開源出了大量優秀的服務注冊與發現元件,包括不僅限于 Consul、Etcd、Zookeeper、Eureka。它們之間各有千秋,在元件選型時可以根據自身業務的需要進行選擇和改造,接下來我們主要對 Consul、Etcd、Zookeeper 作一些簡單的介紹和比較。

基于 Raft 算法、開箱即用的服務發現系統 Consul

Consul 由 HashiCorp 開源,是支援多個平台的分布式高可用系統。Consul 使用 Golang 語言實作,主要用于實作分布式系統的服務發現與配置,滿足 AP 特性。Consul 是分布式、高可用和可橫向擴充的,提供以下主要特性:

  • 服務發現:可以使用 HTTP 或者 DNS 的方式将服務執行個體的中繼資料注冊到 Consul,和通過 Consul 發現所依賴服務的中繼資料清單。
  • 檢查檢查:Consul 提供定時的健康檢查機制,定時請求注冊到 Consul 中的服務執行個體提供的健康檢查接口,将異常傳回的服務執行個體标記為不健康。
  • Key/Value:Consul 提供了 Key/Value 存儲功能,可以通過簡單的 HTTP 接口進行使用。
  • 多資料中心:Consul 使用 Raft算法來保證資料一緻性,提供了開箱即用的多資料中心功能。

服務執行個體與 Consul 的互動如下圖所示:

【華為雲專家原創】 服務注冊與發現如何滿足服務治理?

Consul 與服務執行個體的互動過程

通過 Consul 實作服務注冊與發現中心的調用過程如下:

  1. Producer在啟動之初會通過 /register 接口将自己的服務執行個體中繼資料注冊到 Consul 中;
  2. Consul 通過 Producer 提供的健康檢查接口 /health 定時檢查 Producer 的服務執行個體狀态;
  3. Consumer 請求 Consul 的接口擷取 Producer 服務的中繼資料;
  4. Consumer 從 Consul 中傳回的 Producer 服務執行個體中繼資料清單中選擇合适的服務執行個體,使用其配置的 IP 和端口資訊發起服務調用,如圖 7-1 中 Consumer 調用 Producer 的 /service 接口。

Consul 是一個高可用的分布式系統,支援多資料中心部署。一個 Consul 叢集由多個部署和運作了 Consul Agent 的節點組成。Consul 叢集中存在兩種角色,Server 和 Client。每個 Consul Agent 負責對本地的服務進行監控檢查,并将查詢請求轉發到 Server 中進行處理。Consul 簡單的架構圖如下圖所示:

【華為雲專家原創】 服務注冊與發現如何滿足服務治理?

Consul 架構圖

從上圖可知,Consul 主要由 Consul Client 和 Consul Server 組成,且 Consul 使用 Gossip 協定來管理成員和廣播消息到叢集。

Consul 作為一個開箱即用、高可用分布式服務發現和配置系統,可以很友善地為微服務的服務治理提供強有力的支援。在後面的課時中,我們将實作一個 Consul 的用戶端,将我們自身的 Web 服務注冊到 Consul 中,以供其他服務或者網關調用。

基于 HTTP 協定的分布式 key/Value 存儲系統 Etcd

Etcd 是由 CoreOS 開源,采用 Golang 語言編寫的分布式、高可用的 Key/Value 存儲系統,主要用于服務發現和配置共享。Ectd 的經典應用場景有:

  • Key/Value 存儲:Etcd 支援 HTTP RESTful API,提供強一緻性、高可用的資料存儲能力。
  • 服務發現:通過在 Etcd 中注冊某個服務的目錄,服務執行個體連接配接 Etcd 并在目錄下釋出對應 IP 和 Port 以供調用方使用,可以有效實作服務注冊與發現的功能;
  • 消息釋出與訂閱:通過 Etcd 的 Watcher 機制,可以使訂閱者訂閱他們關心的目錄。當消息釋出者修改被監控的目錄内容時,可以将變化實時通知給訂閱者。
【華為雲專家原創】 服務注冊與發現如何滿足服務治理?

Etcd 的叢集的基本架構圖

相對于其他的元件來講,Etcd 更為輕量級,部署簡單,支援 HTTP 接口。它可以為服務發現提供一個穩定高可用的消息注冊倉庫,為微服務協同工作提供了有力的支援。

重量級一緻性服務系統 Zookeeper

Zookeeper 作為 Hadoop 和 Hbase 的重要元件,是一個開源的分布式應用協調服務,目前由 Apache 基金會維護,采用 Java 語言開發。Zookeeper 緻力于為分布式應用提供一緻性服務,它的設計目标是将分布式系統中那些複雜且容易出錯的服務封裝為簡單高效的接口以供開發人員使用。

Zookeeper 底層隻提供了兩個功能,管理用戶端送出的資料和為用戶端程式提供資料節點的監聽服務。它是一個典型的分布式資料一緻性解決方案,基于 ZooKeeper 可以實作服務發現與注冊、消息釋出與訂閱、分布式協調與通知、分布式鎖、Master 選舉、叢集管理和分布式隊列等諸多功能。

Zookeeper 叢集中存在三種角色,分别為 Leader、Follower 和 Observer,架構圖如圖所示:

【華為雲專家原創】 服務注冊與發現如何滿足服務治理?

Zookeeper 架構圖

Zookeeper 通過 ZAB 協定來保證其資料一緻性。ZAB 不是一種通用的分布式一緻性算法,它是在 Paxos 算法的基礎上,為 Zookeeper 特别設計的崩潰可恢複的原子消息廣播協定。ZAB 協定主要包含兩種基本模式,崩潰恢複和消息廣播:

  • 崩潰恢複模式:在服務啟動或者 Leader 伺服器崩潰時,ZAB協定就會進入崩潰恢複模式,在所有的 Follower 中選舉出 Leader。當選舉了新的 Leader 後,叢集中有半數與新的Leader 完成狀态同步後就會退出恢複模式,進入到消息廣播模式。
  • 消息廣播模式:ZAB協定消息廣播過程使用的是一個原子廣播協定,類似于一個二階段送出,但是又有所不同,并非所有 Follower 節點都傳回 Ack 才進行一緻性事務完成,而是隻需要半數以上即可送出完成一個事務廣播。

Zookeeper 為分布式系統提供協調服務,能夠有效地支援微服務架構的服務注冊和發現機制。同時 Zookeeper 中提供的其他資料一緻性解決方案,能夠有力支撐微服務中分布式業務的開發。

服務注冊與發現元件的對比

以上介紹的三種服務注冊與發現元件在業界都已經有了廣泛的應用,在很多大公司的項目中都能看到它們的身影,比如 Zookeeper 在 Hadoop 體系中發揮了極其重要的分布式協調作用。下面将從特性方面比較他們的異同:

【華為雲專家原創】 服務注冊與發現如何滿足服務治理?

從軟體的生态出發,Consul 是以服務發現和配置作為主要功能目标,附帶提供了 Key/Value 存儲,相對于 Etcd 和 Zookeeper 來講業務範圍較小,更适合于服務注冊與發現。Etcd 和 Zookeeper 屬于通用的分布式一緻性存儲系統,被應用于分布式系統的協調工作中,使用範圍抽象,具體的業務場景需要開發人員自主實作,如服務發現、分布式鎖等。Zookeeper 具備廣大的周邊生态,在分布式系統中得到了廣泛的使用;而 Etcd 以簡單易用的特性吸引了大量開發人員,在目前火熱的 Kubernetes 中也有應用。僅從服務注冊與發現元件的需求來看,選擇 Consul 作為服務注冊與發現中心能夠取得更好的效果;如果系統存在其他分布式一緻性協作需求,選擇 Etcd 和 Zookeeper 反而能夠提供更多的服務支援。

小結

本文主要介紹了服務注冊與發現的原理,以及常用的幾種服務注冊與發現元件介紹對比。服務注冊與發現在微服務架構中是各個微服務之間的協調者,是以掌握服務注冊與發現的基本原理,正确使用服務注冊與發現元件是非常重要的一件事。在接下來的文章中,我們将基于 Consul 實作 Go 微服務的服務注冊與發現。

本文分享自華為雲社群《【華為雲專家原創】 服務注冊與發現如何滿足服務治理?》,原文作者:aoho 。

點選關注,第一時間了解華為雲新鮮技術~

繼續閱讀