微服務(wù)架構(gòu)的服務(wù)發(fā)現(xiàn)設(shè)計(jì)模式
在我們服務(wù)使用 REST API 調(diào)用服務(wù)時(shí),是需要知道服務(wù)實(shí)例的網(wǎng)絡(luò)位置(IP 地址和端口)。
在服務(wù)器上運(yùn)行的傳統(tǒng)應(yīng)用程序中服務(wù)實(shí)例的api通常是靜態(tài)的。在現(xiàn)在基于云的微服務(wù)應(yīng)用程序中,api通常不是那么簡(jiǎn)單設(shè)置。由于自動(dòng)縮放、故障和升級(jí),服務(wù)實(shí)例會(huì)動(dòng)態(tài)變化。因此,我們必須在客戶端代碼中使用服務(wù)發(fā)現(xiàn)。
1、服務(wù)發(fā)現(xiàn)
服務(wù)的IP地址不能在客戶端靜態(tài)配置。需要使用動(dòng)態(tài)服務(wù)發(fā)現(xiàn)。從概念上講,服務(wù)發(fā)現(xiàn)非常簡(jiǎn)單,它的主要組件是一個(gè)服務(wù)注冊(cè)表,它包含一個(gè)應(yīng)用程序服務(wù)實(shí)例的網(wǎng)絡(luò)位置列表。
當(dāng)服務(wù)實(shí)例啟動(dòng)和停止時(shí),服務(wù)注冊(cè)表會(huì)更新。服務(wù)發(fā)現(xiàn)機(jī)制通過(guò)查詢服務(wù)注冊(cè)表以獲取可用服務(wù)實(shí)例的列表,并在客戶端調(diào)用服務(wù)時(shí)將請(qǐng)求路由到其中一個(gè)。
2、應(yīng)用程序級(jí)服務(wù)發(fā)現(xiàn)模式
應(yīng)用程序的服務(wù)及其客戶端可以與服務(wù)注冊(cè)中心交互以實(shí)現(xiàn)服務(wù)發(fā)現(xiàn)。每個(gè)服務(wù)實(shí)例向服務(wù)注冊(cè)表注冊(cè)其網(wǎng)絡(luò)位置,在調(diào)用服務(wù)之前從服務(wù)注冊(cè)中心請(qǐng)求服務(wù)實(shí)例列表。然后,客戶端向其中一個(gè)實(shí)例發(fā)送請(qǐng)求。
這種方法是兩種模式的組合。
- 自注冊(cè)模式:在啟動(dòng)期間,服務(wù)實(shí)例調(diào)用注冊(cè)中心的注冊(cè) API 來(lái)注冊(cè)其網(wǎng)絡(luò)位置,注冊(cè)中心要求服務(wù)實(shí)例定期調(diào)用心跳 API 以防止其注冊(cè)過(guò)期。當(dāng)服務(wù)實(shí)例關(guān)閉時(shí),它會(huì)從服務(wù)注冊(cè)表中注銷自己。
- 客戶端發(fā)現(xiàn)模式:為了調(diào)用服務(wù),服務(wù)客戶端向服務(wù)注冊(cè)中心查詢服務(wù)實(shí)例列表。客戶端使用負(fù)載平衡算法來(lái)選擇服務(wù)實(shí)例,然后由客戶端請(qǐng)求選定的實(shí)例。
Netflix 和 Pivotal 已經(jīng)普及了企業(yè)級(jí)服務(wù)發(fā)現(xiàn)。例如,Netflix 的 Eureka 是一個(gè)高可用的服務(wù)注冊(cè)中心。Netflix 組件可以很容易地與 Spring Cloud 一起使用,這是一個(gè)由 Pivotal 開(kāi)發(fā)的基于 Spring 的框架。基于 Spring Cloud 的服務(wù)向 Eureka 注冊(cè),基于 Spring Cloud 的客戶端使用 Eureka 發(fā)現(xiàn)服務(wù)。
3、應(yīng)用層服務(wù)發(fā)現(xiàn)的缺點(diǎn)
- 需要特定語(yǔ)言的服務(wù)發(fā)現(xiàn)庫(kù)。
- 需要運(yùn)維人員維護(hù)設(shè)置和管理服務(wù)注冊(cè)表。
- 當(dāng)服務(wù)實(shí)例正在運(yùn)行但不處理請(qǐng)求時(shí),會(huì)出現(xiàn)從服務(wù)注冊(cè)中心遺漏注銷的可行性。
4、平臺(tái)提供的服務(wù)發(fā)現(xiàn)模式
許多部署平臺(tái)例如 Docker 和 Kubernetes,都內(nèi)置了服務(wù)注冊(cè)表和服務(wù)發(fā)現(xiàn)機(jī)制。每個(gè)服務(wù)都分配有一個(gè) DNS 名稱、一個(gè)虛擬 IP (VIP) 地址和一個(gè)解析為 VIP 地址的 DNS 名稱。
服務(wù)客戶端請(qǐng)求 DNS 名稱/VIP,部署平臺(tái)自動(dòng)將請(qǐng)求路由到可用服務(wù)實(shí)例。這樣服務(wù)注冊(cè)、服務(wù)發(fā)現(xiàn)、請(qǐng)求路由等全部由部署平臺(tái)處理。服務(wù)注冊(cè)表跟蹤部署平臺(tái)中已部署服務(wù)的 IP 地址。
這種方法是兩種模式的組合:
- 第 三 方注冊(cè)模式:不是服務(wù)向服務(wù)注冊(cè)中心注冊(cè)自己,而是由第三方注冊(cè)商(通常是部署平臺(tái)的一部分)進(jìn)行注冊(cè)。注冊(cè)器在啟動(dòng)時(shí)向服務(wù)注冊(cè)中心注冊(cè)服務(wù)實(shí)例。當(dāng)實(shí)例關(guān)閉時(shí),注冊(cè)器會(huì)從服務(wù)注冊(cè)表中取消注冊(cè)服務(wù)實(shí)例。
- 服務(wù)器端發(fā)現(xiàn)模式:它不是客戶端查詢服務(wù)注冊(cè)表,而是向 DNS 名稱發(fā)出請(qǐng)求,DNS 名稱解析為查詢注冊(cè)表并負(fù)載平衡請(qǐng)求的請(qǐng)求路由器。AWS 彈性負(fù)載均衡器 (ELB) 是服務(wù)器端發(fā)現(xiàn)路由器的一個(gè)示例。客戶端向 ELB 發(fā)送 HTTP/TCP 請(qǐng)求,ELB 在一組 EC2 實(shí)例之間對(duì)流量進(jìn)行負(fù)載平衡。ELB 還充當(dāng)服務(wù)注冊(cè)表。實(shí)例通過(guò) API 調(diào)用顯式注冊(cè)到 ELB,或者作為自動(dòng)擴(kuò)展組的一部分自動(dòng)注冊(cè)。
5、基于平臺(tái)的服務(wù)發(fā)現(xiàn)的好處
- 部署平臺(tái)處理服務(wù)發(fā)現(xiàn)的所有工作。
- 服務(wù)和客戶端都不包含任何用于服務(wù)發(fā)現(xiàn)的代碼。
- 服務(wù)發(fā)現(xiàn)對(duì)所有服務(wù)和客戶端都可用,無(wú)論它們是用什么語(yǔ)言編寫(xiě)的。
6、基于平臺(tái)的服務(wù)發(fā)現(xiàn)的缺點(diǎn)
- 只能發(fā)現(xiàn)已使用該平臺(tái)部署的服務(wù)。