聊聊分布式系統(tǒng)中的服務(wù)發(fā)現(xiàn)!
在分布式系統(tǒng)中,為了方便多個服務(wù)需要在網(wǎng)絡(luò)上相互交互,我們需要一種機(jī)制使得這些服務(wù)能夠有效地相互查找和通信,因此,本文我們將探討一種常見的方案:服務(wù)發(fā)現(xiàn)。
一、什么是服務(wù)發(fā)現(xiàn)?
服務(wù)發(fā)現(xiàn)是一種允許在分布式系統(tǒng)中自動檢測和追蹤網(wǎng)絡(luò)中的各個服務(wù)實例,它主要解決的問題是服務(wù)的動態(tài)注冊、查找和負(fù)載均衡。
二、服務(wù)發(fā)現(xiàn)的類型
通常來說服務(wù)發(fā)現(xiàn)有兩種主要類型:客戶端發(fā)現(xiàn)和服務(wù)器端發(fā)現(xiàn)。
1.客戶端發(fā)現(xiàn)
在客戶端發(fā)現(xiàn)中,服務(wù)使用者負(fù)責(zé)查詢服務(wù)注冊表以查找可用的服務(wù)實例,然后在這些實例之間對請求進(jìn)行負(fù)載均衡。
優(yōu)勢:易于實施和理解。減少中央負(fù)載均衡器上的負(fù)載。
缺點:
- 使用者需要實現(xiàn)發(fā)現(xiàn)邏輯。
- 注冊表協(xié)議中的更改需要客戶端中的更改。
比如,Netflix Eureka就是一個客戶端服務(wù)發(fā)現(xiàn)的注冊中心。
2.服務(wù)器端發(fā)現(xiàn)
在服務(wù)器端發(fā)現(xiàn)中,服務(wù)使用者向中介(負(fù)載均衡器或 API 網(wǎng)關(guān))發(fā)出請求,然后中介查詢服務(wù)注冊表并將請求路由到相應(yīng)的服務(wù)實例。
優(yōu)勢:
- 集中發(fā)現(xiàn)邏輯,降低使用者的復(fù)雜性。
- 更易于管理和更新發(fā)現(xiàn)協(xié)議。
缺點
- 引入了一個額外的網(wǎng)絡(luò)躍點。
- 負(fù)載均衡器可能成為單點故障。
比如,AWS Elastic Load Balancer(ELB)與 AWS服務(wù)注冊表集成,以實現(xiàn)服務(wù)器端發(fā)現(xiàn)。
三、服務(wù)發(fā)現(xiàn)如何工作?
1.三個組件
服務(wù)發(fā)現(xiàn)包含三個重要的組件:服務(wù)提供者、服務(wù)使用者和服務(wù)注冊表,它們之間的關(guān)系如下圖:
- 服務(wù)提供者(Service Provider):服務(wù)提供者在進(jìn)入系統(tǒng)時向服務(wù)注冊中心注冊,并在離開系統(tǒng)時取消注冊。
- 服務(wù)使用者(Service Consumer):服務(wù)使用者從服務(wù)注冊表中獲取提供者的信息,然后連接到服務(wù)提供者。
- 服務(wù)注冊表(Service Registry):服務(wù)注冊表是保存服務(wù)提供者的相關(guān)信息,當(dāng)服務(wù)提供者有變更時,注冊表也能感知,以便客戶端可以通過從服務(wù)注冊表獲取最新數(shù)據(jù)。
2.工作原理
- 服務(wù)注冊:每個服務(wù)實例在啟動時會向一個服務(wù)注冊中心(Service Registry)注冊自己,包括服務(wù)名、實例ID、IP地址、端口號等信息。
- 服務(wù)發(fā)現(xiàn):客戶端需要訪問某個服務(wù)時,會先查詢服務(wù)注冊中心以獲取可用的服務(wù)實例列表,然后選擇一個實例進(jìn)行調(diào)用。
- 健康檢查:服務(wù)注冊中心定期對注冊的服務(wù)實例進(jìn)行健康檢查,確保只有健康的實例在列表中,故障實例會被移除。
- 負(fù)載均衡:在客戶端從服務(wù)注冊中心獲取服務(wù)實例列表后,通常會使用某種負(fù)載均衡策略(如輪詢、隨機(jī)、最小連接數(shù)等)來選擇具體的服務(wù)實例進(jìn)行請求。
四、服務(wù)發(fā)現(xiàn)的重要性
- 減少手動配置:服務(wù)可以動態(tài)發(fā)現(xiàn)并相互連接,無需手動配置和硬編碼網(wǎng)絡(luò)位置。
- 改進(jìn)的可擴(kuò)展性:隨著新服務(wù)實例的添加或刪除,服務(wù)發(fā)現(xiàn)可確保其他服務(wù)能夠無縫適應(yīng)不斷變化的環(huán)境。
- 增強的容錯能力:服務(wù)發(fā)現(xiàn)機(jī)制通常包括運行狀況檢查,使系統(tǒng)能夠自動將流量從失敗的服務(wù)實例中重新路由出去。
- 簡化管理:擁有中央服務(wù)注冊表可以更輕松地監(jiān)視、管理和排除整個系統(tǒng)的故障。
五、常用服務(wù)發(fā)現(xiàn)工具
下面列舉了幾個分布式環(huán)境下常用的服務(wù)發(fā)現(xiàn)工具。
1.Eureka
Eureka Server采用的是Peer to Peer對等通信,它是一種去中心化的架構(gòu),每一個 Peer都是對等的。節(jié)點之間通過彼此互相注冊來提高可用性,每個節(jié)點需要添加一個或多個有效的 serviceUrl指向其他節(jié)點。每個節(jié)點都可被視為其他節(jié)點的副本。,其原理圖如下:
Eureka采用的是 ACP理論中的 AP原則,因此,只要 Eureka集群中有一臺 Eureka還在,就能保證注冊服務(wù)可用。
2.Consul
Consul 是一個分布式、高度可用的服務(wù)發(fā)現(xiàn)和配置系統(tǒng),它提供服務(wù)發(fā)現(xiàn)、運行狀況檢查、鍵值存儲和多數(shù)據(jù)中心支持,其原理圖如下:
Consul采用的是 ACP理論中的 CP模型,使用 Raft算法來保證強一致性,支持多數(shù)據(jù)中心,可以避免單數(shù)據(jù)中心的單點故障,而其部署則需要考慮網(wǎng)絡(luò)延遲, 分片等情況等。
3.etcd + kubernetes
etcd 是一個分布式鍵值存儲,可用于服務(wù)發(fā)現(xiàn)和配置管理,其原理圖如下:
etcd 是一種高度一致的分布式鍵值存儲,它提供了一種可靠的方法來存儲分布式系統(tǒng)或機(jī)器集群需要訪問的數(shù)據(jù)。它可以在網(wǎng)絡(luò)分區(qū)期間優(yōu)雅地處理領(lǐng)導(dǎo)者選舉,并且可以容忍機(jī)器故障,即使在領(lǐng)導(dǎo)者節(jié)點中也是如此。
Kubernetes 是一個容器編排平臺,具有內(nèi)置的服務(wù)發(fā)現(xiàn)機(jī)制。它使用標(biāo)簽和注釋來管理服務(wù)實例,并通過 DNS提供服務(wù)發(fā)現(xiàn)。
4.Nacos
Nacos是阿里開源的,支持基于 DNS和基于 RPC的服務(wù)發(fā)現(xiàn),它即支持 CP模式也支持 AP模式,可以通過命令的方式切換,其原理圖如下:
五、總結(jié)
本文,我們分析了什么是服務(wù)發(fā)現(xiàn)以及它在分布式系統(tǒng)中是如何工作的?對于服務(wù)發(fā)現(xiàn)我們需要掌握其核心模型:
- 服務(wù)提供者(Service Provider):服務(wù)提供者在進(jìn)入系統(tǒng)時向服務(wù)注冊中心注冊,并在離開系統(tǒng)時取消注冊。
- 服務(wù)使用者(Service Consumer):服務(wù)使用者從服務(wù)注冊表中獲取提供者的信息,然后連接到服務(wù)提供者。
- 服務(wù)注冊表(Service Registry):服務(wù)注冊表是保存服務(wù)提供者的相關(guān)信息,當(dāng)服務(wù)提供者有變更時,注冊表也能感知,以便客戶端可以通過從服務(wù)注冊表獲取最新數(shù)據(jù)。
最后,我們通過分析幾個常見的服務(wù)發(fā)現(xiàn)工具,盡管它們的實現(xiàn)細(xì)節(jié)略有差異,但是它們的核心模型是一樣的,只要能抓住核心模型,即便出現(xiàn)新的框架或者工具,我們也可以快速上手。