【華為云專家原創】 服務注冊與發現如何滿足服務治理?(華為云云享專家)
在單體應用向微服務架構演進的過程中,原本的巨石型應用會按照業務需求被拆分成多個微服務,每個服務提供特定的功能,并可能依賴于其他的微服務。每個微服務實例都可以動態部署,服務實例之間的調用通過輕量級的遠程調用方式(HTTP、消息隊列等)實現,它們之間通過預先定義好的接口進行訪問。

由于服務實例是動態部署,每個服務實例的地址和服務信息都可能動態變化,勢必需要一個中心化的組件對各個服務實例的信息進行管理,該組件管理了各個部署好的服務實例元數據,包括不僅限于服務名、IP 地址、端口號、服務描述和服務狀態等。
什么是服務注冊與發現?
服務注冊與發現主要包含兩部分:服務注冊與服務發現。服務注冊是指服務實例啟動時將自身信息注冊到服務注冊與發現中心,并在運行時通過心跳等方式向服務注冊與發現中心匯報自身服務狀態;服務發現是指服務實例向服務注冊與發現中心獲取其他服務實例信息,用于進行接下來的遠程調用。接下來讓我們介紹服務注冊與發現中心的職責和服務實例進行服務注冊的基本流程,以及分布式系統中數據同步的基本原理 CAP。
服務注冊與發現中心有什么功能?
在傳統單體應用中,應用都是部署在固定的物理機器或者云平臺上,他們之間的調用一般是通過固定在代碼內部或者配置文件的服務地址和端口直接發起。由于應用數量較少,系統結構復雜度不高,開發人員和運維人員可以較為輕松地進行管理和配置。
隨著應用架構向微服務架構遷移,服務數量的增加和動態部署動態擴展的特性,使得服務地址和端口在運行時是隨時可變的。對此,我們需要一個額外的中心化組件統一管理動態部署的微服務應用的服務實例元數據,一般稱它為服務注冊與發現中心。服務注冊與發現中心主要有以下的職責:
管理當前注冊到服務注冊與發現中心的微服務實例元數據信息,包括服務實例的 服務名、IP 地址、端口號、服務描述和服務狀態等;
與注冊到服務發現與注冊中心的微服務實例維持心跳,定期檢查注冊表中的服務實例是否在線,并剔除無效服務實例信息;
提供服務發現能力,為服務調用方提供服務提供方的服務實例元數據。
在單體應用向微服務架構演進的過程中,原本的巨石型應用會按照業務需求被拆分成多個微服務,每個服務提供特定的功能,并可能依賴于其他的微服務。每個微服務實例都可以動態部署,服務實例之間的調用通過輕量級的遠程調用方式(HTTP、消息隊列等)實現,它們之間通過預先定義好的接口進行訪問。
由于服務實例是動態部署,每個服務實例的地址和服務信息都可能動態變化,勢必需要一個中心化的組件對各個服務實例的信息進行管理,該組件管理了各個部署好的服務實例元數據,包括不僅限于服務名、IP 地址、端口號、服務描述和服務狀態等。
什么是服務注冊與發現?
服務注冊與發現主要包含兩部分:服務注冊與服務發現。服務注冊是指服務實例啟動時將自身信息注冊到服務注冊與發現中心,并在運行時通過心跳等方式向服務注冊與發現中心匯報自身服務狀態;服務發現是指服務實例向服務注冊與發現中心獲取其他服務實例信息,用于進行接下來的遠程調用。接下來讓我們介紹服務注冊與發現中心的職責和服務實例進行服務注冊的基本流程,以及分布式系統中數據同步的基本原理 CAP。
在傳統單體應用中,應用都是部署在固定的物理機器或者云平臺上,他們之間的調用一般是通過固定在代碼內部或者配置文件的服務地址和端口直接發起。由于應用數量較少,系統結構復雜度不高,開發人員和運維人員可以較為輕松地進行管理和配置。
隨著應用架構向微服務架構遷移,服務數量的增加和動態部署動態擴展的特性,使得服務地址和端口在運行時是隨時可變的。對此,我們需要一個額外的中心化組件統一管理動態部署的微服務應用的服務實例元數據,一般稱它為服務注冊與發現中心。服務注冊與發現中心主要有以下的職責:
管理當前注冊到服務注冊與發現中心的微服務實例元數據信息,包括服務實例的 服務名、IP 地址、端口號、服務描述和服務狀態等;
與注冊到服務發現與注冊中心的微服務實例維持心跳,定期檢查注冊表中的服務實例是否在線,并剔除無效服務實例信息;
提供服務發現能力,為服務調用方提供服務提供方的服務實例元數據。
通過服務發現與注冊中心,可以很方便地管理系統中動態變化的服務實例信息。與此同時,它也可能成為系統的瓶頸和故障點。因為服務之間的調用信息來自于服務注冊與發現中心,當它不可用時,服務之間的調用可能無法正常進行。因此服務發現與注冊中心一般會集群化部署,提供高可用性和高穩定性。
在本質上來講,微服務應用屬于分布式系統的一種落地實踐,而分布式系統最大的難點是處理各個節點之間數據狀態的一致性。即使是倡導無狀態的 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 作一些簡單的介紹和比較。
Consul 由 HashiCorp 開源,是支持多個平臺的分布式高可用系統。Consul 使用 Golang 語言實現,主要用于實現分布式系統的服務發現與配置,滿足 AP 特性。Consul 是分布式、高可用和可橫向擴展的,提供以下主要特性:
服務發現:可以使用 HTTP 或者 DNS 的方式將服務實例的元數據注冊到 Consul,和通過 Consul 發現所依賴服務的元數據列表。
檢查檢查:Consul 提供定時的健康檢查機制,定時請求注冊到 Consul 中的服務實例提供的健康檢查接口,將異常返回的服務實例標記為不健康。
Key/Value:Consul 提供了 Key/Value 存儲功能,可以通過簡單的 HTTP 接口進行使用。
多數據中心:Consul 使用 Raft算法來保證數據一致性,提供了開箱即用的多數據中心功能。
服務實例與 Consul 的交互如下圖所示:
通過 Consul 實現服務注冊與發現中心的調用過程如下:
Producer在啟動之初會通過 /register 接口將自己的服務實例元數據注冊到 Consul 中;
Consul 通過 Producer 提供的健康檢查接口 /health 定時檢查 Producer 的服務實例狀態;
Consumer 請求 Consul 的接口獲取 Producer 服務的元數據;
Consumer 從 Consul 中返回的 Producer 服務實例元數據列表中選擇合適的服務實例,使用其配置的 IP 和端口信息發起服務調用,如圖 7-1 中 Consumer 調用 Producer 的 /service 接口。
Consul 是一個高可用的分布式系統,支持多數據中心部署。一個 Consul 集群由多個部署和運行了 Consul Agent 的節點組成。Consul 集群中存在兩種角色,Server 和 Client。每個 Consul Agent 負責對本地的服務進行監控檢查,并將查詢請求轉發到 Server 中進行處理。Consul 簡單的架構圖如下圖所示:
從上圖可知,Consul 主要由 Consul Client 和 Consul Server 組成,且 Consul 使用 Gossip 協議來管理成員和廣播消息到集群。
Consul 作為一個開箱即用、高可用分布式服務發現和配置系統,可以很方便地為微服務的服務治理提供強有力的支持。在后面的課時中,我們將實現一個 Consul 的客戶端,將我們自身的 Web 服務注冊到 Consul 中,以供其他服務或者網關調用。
Etcd 是由 CoreOS 開源,采用 Golang 語言編寫的分布式、高可用的 Key/Value 存儲系統,主要用于服務發現和配置共享。Ectd 的經典應用場景有:
Key/Value 存儲:Etcd 支持 HTTP RESTful API,提供強一致性、高可用的數據存儲能力。
服務發現:通過在 Etcd 中注冊某個服務的目錄,服務實例連接 Etcd 并在目錄下發布對應 IP 和 Port 以供調用方使用,可以有效實現服務注冊與發現的功能;
消息發布與訂閱:通過 Etcd 的 Watcher 機制,可以使訂閱者訂閱他們關心的目錄。當消息發布者修改被監控的目錄內容時,可以將變化實時通知給訂閱者。
相對于其他的組件來講,Etcd 更為輕量級,部署簡單,支持 HTTP 接口。它可以為服務發現提供一個穩定高可用的消息注冊倉庫,為微服務協同工作提供了有力的支持。
Zookeeper 作為 Hadoop 和 Hbase 的重要組件,是一個開源的分布式應用協調服務,目前由 Apache 基金會維護,采用 Java 語言開發。Zookeeper 致力于為分布式應用提供一致性服務,它的設計目標是將分布式系統中那些復雜且容易出錯的服務封裝為簡單高效的接口以供開發人員使用。
Zookeeper 底層只提供了兩個功能,管理客戶端提交的數據和為客戶端程序提供數據節點的監聽服務。它是一個典型的分布式數據一致性解決方案,基于 ZooKeeper 可以實現服務發現與注冊、消息發布與訂閱、分布式協調與通知、分布式鎖、Master 選舉、集群管理和分布式隊列等諸多功能。
Zookeeper 集群中存在三種角色,分別為 Leader、Follower 和 Observer,架構圖如圖所示:
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 微服務的服務注冊與發現。
云原生 分布式 微服務 Go
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。