微服務4:服務註冊與發現

★ 微服務系列

微服務1:微服務及其演進史

微服務2:微服務全景架構 

微服務3:微服務拆分策略

微服務4:服務註冊與發現

1 微服務的註冊與發現

我們前面在全景架構中對服務註冊與發現做了大致的說明,本章我們著重詳細說明微服務下註冊與發現的這個能力。

微服務註冊與發現類似於生活中的”電話通訊錄”的概念,它記錄了通訊錄服務和電話的映射關係。在分散式架構中,服務會註冊進去,當服務需要調用其它服務時,就這裡找到服務的地址,進行調用。

步驟如下:

1、你先要把”好友某某”記錄在通訊錄中。

2、撥打電話的時候通過通訊錄中找到”好友某某”,並撥通回電話。

3、當好友某某電話號碼更新的時候,需要通知到你,並修改通訊錄服務中的號碼。

從這個過程中我們看到了一些特點:

1、把 “好友某某” 的電話號碼寫入通訊錄中,統一在通訊錄中維護,後續號碼變更也是更新到通訊錄中,這個過程就是服務註冊的過程。

2、後續我們通過”好友某某”就可以定位到通訊錄中的電話號碼,並撥通電話,這個過程理解為服務發現的過程。

而我們微服務架構中的服務註冊與發現結構如下圖所示

 

圖片中是一個典型的微服務架構,這個結構中主要涉及到三大角色:

provider – 服務提供者

consumer – 服務消費者

register center – 註冊中心

它們之間的關係大致如下:

1、每個微服務在啟動時,將自己的網路地址等資訊(微服務的ServiceName、IP、Port、MetaData等)註冊到註冊中心,註冊中心存儲這些數據。

2、服務消費者從註冊中心查詢服務提供者的地址,並通過該地址調用服務提供者的介面。

3、各個微服務與註冊中心使用一定機制(例如心跳)通訊。如果註冊中心與某微服務長時間無法通訊,就會註銷該實例。

優點如下:

1、解耦:服務消費者跟服務提供者解耦,各自變化,不互相影響

2、擴展:服務消費者和服務提供者增加和刪除新的服務,對於雙方沒有任何影響

3、中介者設計模式:用一個中介對象來封裝一系列的對象交互,這是一種多對多關係的中介者模式。

從功能上拆開主要有三塊:服務註冊、服務發現,和註冊中心。我們一個一個來看。

1.1 服務註冊

如圖中,為Register註冊中心註冊一個服務資訊,會將服務的資訊:ServiceName、IP、Port以及服務實例MetaData元數據資訊寫入到註冊中心。當服務發生變化的時候,也可以更新到註冊中心。

 

服務提供者(服務實例) 的服務註冊模型是一種簡單、容易理解、流行的服務註冊模型,其在多種技術生態中都有所體現:

1、在K8S生態中,通過 K8S Service服務資訊,和Pod的 endpoint(用來記錄service對應的pod的訪問地址)來進行註冊。

2、在Spring Cloud生態中,應用名 對應 服務Service,實例 IP + Port 對應 Instance實例。比較典型的就是A服務,後面對應有多個實例做負載均衡。 

3、在其他的註冊組件中,比如 Eureka、Consul,服務模型也都是 服務→ 服務實例。

可以認為服務實例是一個真正的實體的載體,服務是對這些相同能力或者相同功能服務實例的一個抽象。

 

1.2 服務發現

服務發現實際就是我們查詢已經註冊好的服務提供者,比如 p->p.queryService(serviceName),通過服務名稱查詢某個服務是否存在,如果存在,

返回它的所有實例資訊,即一組包含ip 、 port 、metadata元數據資訊的endpoints資訊。

這一組endpoints資訊一般會被快取在本地,如果註冊中心掛掉,可保證段時間內依舊可用,這是去中心化的做法。對於單個 Service 後面有多個 Instance的情況(如上圖),做 load balance。

服務發現的方式一般有兩種:

1、拉取的方式:服務消費方(Consumer)主動向註冊中心發起服務查詢的請求。

2、推送的方式:服務訂閱/通知變更(下發):服務消費方(Consumer)主動向註冊中心訂閱某個服務,當註冊中心中該服務資訊發生變更時,註冊中心主動通知消費者。 

1.3 註冊中心

註冊中心提供的基本能力包括:提供服務註冊、服務發現 以及 健康檢查。

服務註冊跟服務發現上面已經詳細介紹了, 健康檢查指的是指註冊中心能夠感知到微服務實例的健康狀況,便於上游微服務實例及時發現下游微服務實例的健康狀況。採取必備的訪問措施,如避免訪問不健康的實例。

主要的檢查方式包括:

1、服務Provider 進行 TTL 健康彙報(Time To Live,微服務Provider定期向註冊中心彙報健康狀態)。

2、註冊中心主動檢查服務Provider介面。

綜合我們前面的內容,可以總結下註冊中心有如下幾種能力:

1、高可用

這個主要體現在兩個方面。一個方面是,註冊中心本身作為基礎設施層,具備高可用;第二種是就是前面我們說到的去中心化,極端情況下的故障,短時間內是不影響微服務應用的調用的

2、可視化操作

常用的註冊中心,類似 Eureka、Consul 都有比較豐富的管理介面,對配置、服務註冊、服務發現進行可視化管理。

3、高效運維

註冊中心的文檔豐富,對運維的支援比較好,並且對於服務的註冊是動態感知獲取的,方便動態擴容。

4、許可權控制

數據是具有敏感性,無論是服務資訊註冊或服務是調用,需要具備許可權控制能力,避免侵入或越權請求

5、服務註冊推、拉能力

這個前面說過了,微服務應用程式(服務的Consumer),能夠快速感知到服務實例的變化情況,使用拉取或者註冊中心下發的方式進行處理。 

 

2 現下的主流註冊中心

2.1 Eureka

2.1.1 介紹

Eureka是Netflix OSS套件中關於服務註冊和發現的解決方案。因為Spring Cloud 在它的微服務解決方案中對Eureka進行了集成,並作為優先推薦方案進行宣傳,所以早期有用 Spring Cloud 來建設微服務系統的同學會比較熟悉。

目前大量公司的微服務系統中依舊使用Eureka作為註冊中心,它的核心設計思想也被後續大量註冊中心產品借鑒。但目前 Eureka 2.0已經停止維護,所以新的微服務架構設計中,不再建議使用。

Spring Cloud Netflix主要分為兩個部分:

1、Eureka Server: 作為註冊中心Server端,向微服務應用程式提供服務註冊、發現、健康檢查等能力。

2、Eureka Client:  微服務應用程式Client端,用以和Eureka Server進行通訊。

 

 Eureka有比較友好的管理介面,如上圖所示:

1、System Status:顯示當前Eureka Server資訊。

2、Instances Current registered with Eureka:在Eureka Server當前註冊的數據,在Spring Cloud生態中,被註冊的服務可以唄發現並羅列在這個地方。

3、General Info:基本資訊,如cpu、記憶體、環境等。

2.1.2 整體架構

 

Eureka Server可以運行多個實例來構建集群,解決單點問題,但不同於ZooKeeper的選舉leader的過程,Eureka Server採用的是Peer to Peer對等通訊。

所以他有如下特點:

1、去中心化的架構:無master/slave區分,每一個Peer都是對等的。在這種架構中,節點通過彼此互相註冊來提高可用性,每個節點需要添加一個或多個有效的serviceUrl指向其他節點。每個節點都可被視為其他節點的副本。

2、故障轉移/故障恢復:如果某台Eureka Server宕機,Eureka Client的請求會自動切換到新的Eureka Server節點,當宕機的伺服器重新恢復後,Eureka會再次將其納入到伺服器集群管理之中。

3、節點複製:當節點開始接受客戶端請求時,所有的操作都會進行replicateToPeer(節點間複製)操作,將請求複製到其他Eureka Server當前所知的所有節點中。

同理,一個新的Eureka Server節點啟動後,會首先嘗試從鄰近節點獲取所有實例註冊表資訊,完成初始化。

4、CAP模式:複製演算法非強一致性演算法,而是當有數據寫入時,Eureka Server將數據同步給其他的節點,因此Eureka在CAP提系統(一致性、可用性、分區容錯性)是典型的AP系統。

2.1.3 接入Spring Cloud

 

如上圖所示:

1、Provider 服務提供者:服務向註冊中心註冊服務資訊,即 服務 -> 服務實例 數據模型, 同時定時向註冊中心彙報健康檢查,如果一定時間內(一般90s)沒有進行心跳彙報,則會被註冊中心剔除。

所以這邊注意,註冊中心感知到應用下線並進行剔除這個過程可能比較長。 

2、Consumer 服務消費者:服務向註冊中心獲取所需服務對應的服務實例資訊。這邊需要注意,Eureka不支援訂閱,因此在Spring Cloud生態中,通過定時拉取方式從註冊中心中獲取所需的服務實例資訊。

3、Remote Call 遠程調用:Consumer從註冊中心獲取的Provider的實例資訊,通過 Load Balance的策略,確定一個實際的實例,發起遠程調用。 

2.2 ZooKeeper

2.2.1 介紹

作為一個分散式的、開源的協調服務,ZooKeeper實現了一系列基礎功能,包括簡單易用的介面。

這些介面被用來實現服務的註冊與發現功能。並實現一些高級功能,如數據同步、分散式鎖、配置中心、集群選舉、命名服務等。

  

在數據模型上,類似於傳統的文件系統,節點類型分為:

1、持久節點:節點創建後,就一直存在,除非執行刪除操作,主動刪掉這個節點。

2、臨時節點(註冊中心場景下的主要實現機制):臨時節點的生命周期和客戶端會話綁定。也就是說,如果客戶端會話失效,那麼這個節點就會自動被清除掉。

在實際場景下,微服務啟動的時候,會創建一個服務臨時節點,等把服務停止,短時間後節點就沒有了。

 

Zookeeper有如下特點:

1、最終一致性:為客戶端展示同一視圖,這是zookeeper最重要的功能。
2、可靠性:如果消息被到一台伺服器接受,那麼它將被所有的伺服器接受。
3、實時性:Zookeeper不能保證兩個客戶端能同時得到剛更新的數據,如果需要最新數據,應該在讀數據之前調用sync()介面。
4、等待無關(wait-free):慢的或者失效的client不干預快速的client的請求。
5、原子性:更新只能成功或者失敗,沒有中間狀態。
6、順序性:所有Server,同一消息發布順序一致。

2.2.2 整體架構

 

上圖是Zookeeper 的服務架構,他有如下流程:

1、 多個節點組成分散式架構,每個Server在記憶體中存儲一份數據; 

2、通過選舉產生leader,通過 Paxos(帕克索斯)強一致性演算法 進行保證,是典型的CP結構。

3、Leader負責處理數據更新等操作(Zab協議);

2.2.3 接入Dubbo生態

 

上圖中的角色如下:

Provider:提供者,服務發布方

Consumer:消費者, 調用服務方

Container:Dubbo容器.依賴於Spring容器

Registry:註冊中心,當Container啟動時把所有可以提供的服務列表上Registry中進行註冊,告訴Consumer提供了什麼服務,以及服務方的位置

Monitor:監聽器

說明:ZooKeeper在註冊中心方面對Dubbo生態支援的比較好。服務提供者Providerzai Container啟動時主動向註冊中心Registry ZooKeeper中註冊資訊。

服務消費者Consumer啟動時向註冊中心Registry ZooKeeper中訂閱註冊中心,當Provider的資訊發生變化時,註冊中心ZooKeeper會主動向Consumer進行推送通知變更。

這邊注意與Eureka的區別,這是主動推送通知,是註冊中心下發的操作。

2.3 Consul

2.3.1 介紹

Consul是HashiCorp推出的一款軟體,是一個Service Mesh解決方案,提供了功能豐富的控制面功能:

1、Service Discovery(服務發現)

2、Configuration(配置化)

3、Segmentation Functionality

這些功能可以根據需要獨立使用,或者將它們一起使用用來構建完整的Service Mesh。

Consul提供的關鍵功能如下:

1、Service Discovery:服務註冊/發現功能。

2、Health Checking:健康檢查,豐富的健康檢查方式;

3、KV Store:KV存儲功能,可應用多種場景,如動態配置存儲,分散式協調、leader選舉等。

4、Multi DataCenter:多數據中心。

2.3.2 整體架構

  

如上圖為Consul的架構,這邊對技術點做一下說明:

1、Raft: 一種分散式一致性演算法,Consul使用該演算法報紙強一致性,所以也是典型的CP模式

2、Client:Client是一種agent,其將會重定向所有的RPC 請求到Server。Client是無狀態的,其主要參與LAN Gossip協議池。其佔用很少的資源,並且消耗很少的網路頻寬。

3、Server:Server是一種agent,其包含了一系列的責任包括:參與Raft協議寫半數(Raft Quorum)、維護集群狀態、響應RPC響應、和其他Datacenter通過WAN gossip交換資訊和重定向查詢請求至leader或者遠端Datacenter。

4、Datacenter: Datacenter其是私有的、低延遲、高頻寬的網路環境,去除了在公共網路上的網路交互。

5、Consensus: Consensus一致性在leader 選舉、順序執行transaction 上。當這些事務已經提交至有限狀態機(finite-state machine)中,Consul定義consensus作為複製狀態機的一致性。本質上使用實現了Raft協議,對於具體實現細節可參考 Consensus Protocol。

6、Gossip:Consul使用了Serf,其提供了Gossip協議多種用途,Serf提供成員關係、失敗檢查和事件廣播。

7、LAN Gossip: Local Area Network Gossip其包含在同一個網路環境或Datacenter的節點。

8、WAN Gossip: Wide Area Network Gossip 其只包含Server節點,這些server分布在不同的datacenter中,其主要通過網際網路或廣域網相互交流。

9、RPC: 遠程過程調用,用於服務之間的通訊。

10、CAP抉擇:在高可用方面,Consul使用Raft協議作為其分散式一致性協議,本身對故障節點有一定的容忍性,在單個DataCenter中Consul集群中節點的數量控制在2*n + 1個節點,其中n為可容忍的宕機個數,通常為3個節點。

所以是典型的CP模式。

 

根據Consul 的選舉機制和服務原理,我們有兩個注意點 :

1、部署Consul Service 節點應該奇數為宜,因為+1的偶數節點和奇數節點可容忍的故障數是一樣的,比如上圖3和4,另一方面,偶數個節點在選主節點的時候可能會出現二分選票的情況,還得重新選舉。

2、Consul Service 節點數不是越多越好,雖然Server數量越多可容忍的故障數越多,但是Raft進行日誌複製也是很耗時間的,而且Server數量越多,性能越低,所以結合實際場景,一般建議Server部署3個即可。 

有興趣的同學可以去Consul官網看看它的選舉機制,還可以對比下Redis中Sentinel模式。

2.3.3 生態對接

對接Spring Cloud生態

Consul作為註冊中心,集成在Spring Cloud生態。可以看出,跟Eureka對接到Spring Cloud 生態的過程很像。

但是這邊的健康檢查更豐富,可以有多種不同的的Check方式:

  • Script check(Script+ Interval)
  • 基於HTTP請求
  • 基於tcp請求
  • 基於grpc請求

2.4 總結對比

4種註冊中心技術對比
指標 Eureka Zookeeper Consul Etcd
一致性協議 AP CP(Paxos演算法) CP(Raft演算法) CP(Raft演算法)
健康檢查 TTL(Time To Live) TCP Keep Alive TTL\HTTP\TCP\Script Lease TTL KeepAlive
watch/long polling 不支援 watch long polling watch
雪崩保護 支援 不支援 不支援 不支援
安全與許可權 不支援 ACL ACL RBAC
是否支援多數據中心
是否有管理介面 否(可用第三方ZkTools)
Spring Cloud 集成 支援 支援 支援 支援
Dubbo 集成 不支援 支援 支援 不支援
K8S 集成 不支援 不支援 支援 支援

  

這邊是對業內4種註冊中心各緯度上的對比,Eureka是典型的AP類型,Zookeeper和Consul是典型的CP類型。如何選擇取決你的業務是傾向A:高可用性 還是 C:強一致性。

當然,業務是複雜的,在真正的技術選型時,還是要根據自己的實際業務現狀來判斷。有一些傾向,比如你的系統是Spring Cloud體系下,那優先選擇Eureka、Consul。

如果業務會更多向雲原生對齊,則Consul、Etcd會是比較優先的選擇。