在分散式系統中,爲了方便多個服務需要在網路上相互互動,我們需要一種機制使得這些服務能夠有效地相互查詢和通訊,因此,本文我們將探討一種常見的方案:服務發現。
什麼是服務發現?
服務發現是一種允許在分散式系統中自動檢測和追蹤網路中的各個服務例項,它主要解決的問題是服務的動態註冊、查詢和負載均衡。
服務發現的型別
通常來說服務發現有兩種主要型別:客戶端發現和伺服器端發現。
客戶端發現
在客戶端發現中,服務使用者負責查詢服務登錄檔以查詢可用的服務例項,然後在這些例項之間對請求進行負載均衡。
優勢易於實施和理解。 減少中央負載均衡器上的負載。
缺點
使用者需要實現發現邏輯。
登錄檔協議中的更改需要客戶端中的更改。
比如,Netflix Eureka就是一個客戶端服務發現的註冊中心。
伺服器端發現
在伺服器端發現中,服務使用者向中介(負載均衡器或 API 閘道器)發出請求,然後中介查詢服務登錄檔並將請求路由到相應的服務例項。優勢
集中發現邏輯,降低使用者的複雜性。
更易於管理和更新發現協議。
缺點
引入了一個額外的網路躍點。
負載均衡器可能成為單點故障。
比如,AWS Elastic Load Balancer(ELB)與 AWS服務登錄檔整合,以實現伺服器端發現。
服務發現如何工作?
三個元件
服務發現包含三個重要的元件:服務提供者、服務使用者和服務登錄檔,它們之間的關係如下圖:
服務提供者(Service Provider):服務提供者在進入系統時向服務註冊中心註冊,並在離開系統時取消註冊。
服務使用者(Service Consumer):服務使用者從服務登錄檔中獲取提供者的資訊,然後連線到服務提供者。
服務登錄檔(Service Registry):服務登錄檔是儲存服務提供者的相關資訊,當服務提供者有變更時,登錄檔也能感知,以便客戶端可以透過從服務登錄檔獲取最新資料。
工作原理
服務註冊:每個服務例項在啟動時會向一個服務註冊中心(Service Registry)註冊自己,包括服務名、例項ID、IP地址、埠號等資訊。
服務發現:客戶端需要訪問某個服務時,會先查詢服務註冊中心以獲取可用的服務例項列表,然後選擇一個例項進行呼叫。
健康檢查:服務註冊中心定期對註冊的服務例項進行健康檢查,確保只有健康的例項在列表中,故障例項會被移除。
負載均衡:在客戶端從服務註冊中心獲取服務例項列表後,通常會使用某種負載均衡策略(如輪詢、隨機、最小連線數等)來選擇具體的服務例項進行請求。
服務發現的重要性
減少手動配置:服務可以動態發現並相互連線,無需手動配置和硬編碼網路位置。
改進的可擴充套件性:隨著新服務例項的新增或刪除,服務發現可確保其他服務能夠無縫適應不斷變化的環境。
增強的容錯能力:服務發現機制通常包括執行狀況檢查,使系統能夠自動將流量從失敗的服務例項中重新路由出去。
簡化管理:擁有中央服務登錄檔可以更輕鬆地監視、管理和排除整個系統的故障。
常用服務發現工具
下面列舉了幾個分佈式環境下常用的服務發現工具。
Eureka
Eureka Server採用的是Peer to Peer
對等通訊,它是一種去中心化的架構,每一個 Peer都是對等的。節點之間透過彼此互相註冊來提高可用性,每個節點需要新增一個或多個有效的 serviceUrl指向其他節點。每個節點都可被視為其他節點的副本。,其原理圖如下:
Eureka採用的是 ACP理論中的 AP原則,因此,只要 Eureka叢集中有一臺 Eureka還在,就能保證註冊服務可用。
Consul
Consul 是一個分散式、高度可用的服務發現和配置系統,它提供服務發現、執行狀況檢查、鍵值儲存和多資料中心支援,其原理圖如下:
Consul採用的是 ACP理論中的 CP模型,使用 Raft演算法來保證強一致性,支援多資料中心,可以避免單資料中心的單點故障,而其部署則需要考慮網路延遲, 分片等情況等。
etcd + kubernetes
etcd 是一個分散式鍵值儲存,可用於服務發現和配置管理,其原理圖如下:
etcd 是一種高度一致的分散式鍵值儲存,它提供了一種可靠的方法來儲存分散式系統或機器叢集需要訪問的資料。它可以在網路分割槽期間優雅地處理領導者選舉,並且可以容忍機器故障,即使在領導者節點中也是如此。
Kubernetes 是一個容器編排平臺,具有內建的服務發現機制。它使用標籤和註釋來管理服務例項,並透過 DNS提供服務發現。
Nacos
Nacos是阿里開源的,支援基於 DNS 和基於 RPC 的服務發現,它即支援 CP模式也支援 AP模式,可以透過命令的方式切換,其原理圖如下:
總結
本文,我們分析了什麼是服務發現以及它在分散式系統中是如何工作的?對於服務發現我們需要掌握其核心模型:
服務提供者(Service Provider):服務提供者在進入系統時向服務註冊中心註冊,並在離開系統時取消註冊。
服務使用者(Service Consumer):服務使用者從服務登錄檔中獲取提供者的資訊,然後連線到服務提供者。
服務登錄檔(Service Registry):服務登錄檔是儲存服務提供者的相關資訊,當服務提供者有變更時,登錄檔也能感知,以便客戶端可以透過從服務登錄檔獲取最新資料。
最後,我們透過分析幾個常見的服務發現工具,儘管它們的實現細節略有差異,但是它們的核心模型是一樣的,只要能抓住核心模型,即便出現新的框架或者工具,我們也可以快速上手。