微服務實戰(四) 服務發現的可行方案以及實踐案例

2022-09-11 08:09:07 字數 3103 閱讀 8670

這是關於使用微服務架構建立應用系列的第四篇文章。第一篇介紹了微服務架構的模式,討論了使用微服務架構的優缺點。第二和第三篇描述了微服務架構內部的通訊機制。這篇文章中,我們將會**服務發現相關問題。

設想一下,我們正在寫**使用了提供rest api或者thrift

api的服務,為了完成一次服務請求,**需要知道服務例項的網路位置(ip位址和埠)。傳統應用都執行在物理硬體上,服務例項的網路位置都是相對固定的。例如,**可以從乙個經常變更的配置檔案中讀取網路位置。

而對於乙個現代的,基於雲微服務的應用來說,這卻是乙個很麻煩的問題。其架構如圖所示:

服務例項的網路位置都是動態分配的,而且因為擴充套件、失效和公升級等需求,服務例項會經常動態改變,因此,客戶端**需要使用一種更加複雜的服務發現機制。

目前有兩大類服務發現模式:客戶端發現和服務端發現。

我們先來來討論一下客戶端發現。

當使用客戶端發現模式時,客戶端負責決定相應服務例項的網路位置,並且對請求實現負載均衡。客戶端從乙個服務註冊服務中查詢,其中是所有可用服務例項的庫。客戶端使用負載均衡演算法從多個服務例項中選擇出乙個,然後發出請求。

下圖顯示的是這種模式的架構圖:

服務例項的網路位置是在啟動時註冊到服務登錄檔中,並且在服務終止時從登錄檔中刪除。服務例項註冊資訊一般是使用心跳機制來定期重新整理的。

netflix oss提供了一種非常棒的客戶端發現模式。netflix eureka是乙個服務登錄檔,為服務例項註冊管理和查詢可用例項提供了rest api介面。netflix ribbon是一種ipc客戶端,與eureka合同工作實現對請求的負載均衡。我們會在後面詳細討論eureka。

客戶端發現模式也是優缺點分明。這種模式相對比較直接,而且除了服務登錄檔,沒有其它改變的因素。除此之外,因為客戶端知道可用服務登錄檔資訊,因此客戶端可以通過使用雜湊一致性(hashing consistently)變得更加聰明,更加有效的負載均衡。

而這種模式乙個最大的缺點是需要針對不同的程式語言註冊不同的服務,在客戶端需要為每種語言開發不同的服務發現邏輯。

我們分析過客戶端發現後,再看看服務端發現。

另外一種服務發現的模式是服務端發現模式(server-side discovery pattern),下圖展現了這種模式的架構圖:

客戶端通過負載均衡器向某個服務提出請求,負載均衡器向服務登錄檔發出請求,將每個請求**往可用的服務例項。跟客戶端發現一樣,服務例項在服務登錄檔中註冊或者登出。

aws elastic load

balancer(elb)是一種服務端發現路由的例子,elb一般用於均衡從網路來的訪問流量,也可以使用elb來均衡vpc內部的流量。客戶端使用dns,通過elb發出請求(http或者tcp)。elb負載均衡器負責在註冊的ec2例項或者ecs容器之間均衡負載,並不存在乙個分離的服務登錄檔,而ec2例項和ecs例項也向elb註冊。

http服務和類似nginx和nginx plus的負載均衡器都可以作為服務端發現均衡器。例如,這篇博文就描述如何使用consul template來動態配置nginx反向**。consul template是週期性從存放在consul template登錄檔中配置資料重建配置檔案的工具。當檔案發生變化時,會執行乙個命令。在如上部落格中,consul

template產生了乙個nginx.conf檔案,用於配置反向**,然後執行乙個命令,告訴nginx重新調入配置檔案。更複雜的例子可以用http服務登錄檔是服務發現很重要的部分,它是包含服務例項網路位址的資料庫。服務登錄檔需要高可用而且隨時更新。客戶端可以快取從服務登錄檔獲得的網路位址。然而,這些資訊最終會變得過時,客戶端也無法發現服務例項。因此,服務登錄檔由若干使用複製協議保持同步的伺服器構成。

如前所述,netflix eureka是乙個服務登錄檔很好地例子,提供了rest

api註冊和請求服務例項。 服務例項使用post請求註冊網路位址,每30秒必須使用put方法更新登錄檔,使用http

delete請求或者例項超時來登出。可以想見,客戶端可以使用http get請求接受註冊服務例項資訊。

netflix通過在每個aws ec2域執行乙個或者多個eureka服務實現高可用性,每個eureka伺服器都執行在擁有彈性ip位址的ec2例項上。dns text記錄用於儲存eureka集群配置,其中存放從可用域到一系列eureka伺服器網路位址的列表。當eureka服務啟動時,向dns請求接受eureka集群配置,確認同伴位置,給自己分配乙個未被使用的彈性ip位址。

eureka客戶端—服務和服務客戶端—向dns請求發現eureka服務的網路位址,客戶端首選使用同一域內的服務。然而,如果沒有可用服務,客戶端會使用另外乙個可用域的eureka服務。

另外一些服務登錄檔例子包括:

另外,前面強調過,某些系統,例如kubernetes、marathon和aws並沒有獨立的服務登錄檔,對他們來說,服務登錄檔只是乙個內建的功能。

現在我們來看看服務登錄檔的概念,看看服務例項是如何在登錄檔中註冊的。

如前所述,服務例項必須向登錄檔中註冊和登出,如何註冊和登出也有一些不同的方式。一種方式是服務例項自己註冊,也叫自註冊模式(self-registration

pattern);另外一種方式是為其它系統提供服務例項管理的,也叫第三方註冊模式(third party registration

pattern)。我們來看看自註冊模式。

當使用自註冊模式時,服務例項負責在服務登錄檔中註冊和登出。另外,如果需要的話,乙個服務例項也要傳送心跳來保證註冊資訊不會過時。下圖描述了這種架構:

乙個很好地例子是 netflix oss eureka client。eureka客戶端負責處理服務例項的註冊和登出。spring cloud

project,實現了多種模式,包括服務發現,使得向eureka服務例項自動註冊時更容易。可以用@enableeurekaclient注釋j**a配置類。

自註冊模式也有優缺點。乙個優點是,相對簡單,不需要其他系統功能。而乙個主要缺點則是,把服務例項跟服務登錄檔聯絡起來。必須在每種程式語言和框架內部實現註冊**。

另外乙個方法,不需要連線服務和登錄檔,則是第三方註冊模式。

當使用第三方註冊模式時,服務例項並不負責向服務登錄檔註冊,而是由另外乙個系統模組,叫做服務管理器,負責註冊。服務管理器通過查詢部署環境或訂閱事件來跟蹤執行服務的改變。當管理器發現乙個新可用服務,會向登錄檔註冊此服務。服務管理器也負責登出終止的服務例項。下圖是這種模式的架構圖。

Spring Cloud 微服務實戰筆記

傳統開發所有業務邏輯都在乙個應用中,開發,測試,部署隨著需求增加會不斷為單個專案增加不同業務模組 前端展現也不侷限於html檢視模板的形式,後端向前端支援需要更多的介面模組。隨著需求增多,專案變大,單體系統部署在乙個程序內部,往往修改很小的功能,為了部署上線也會影響其他功能。後期維護成本會變得越來越...

微服務 四 服務發現 Nacos

在講服務發現之前需要先普及兩個名詞的概念 有部分人更習慣將服務提供者稱為服務端,服務消費者為客戶端。官網文件 什麼是nacos?官網文件已經解釋的很清楚了,簡單來講,nacos是乙個服務發現元件,也是配置伺服器,主要是幫我們解決了兩個問題 服務發現 解決service a怎麼發現service b的...

微服務實施筆記(四) 部署服務發現

微服務實施筆記 四 部署服務發現 上回書搭建了3個待用的服務。用來模擬實際中的服務。接下來就是把這幾個服務註冊到乙個服務管理中心了。使用consul搭建服務管理中心 在這裡選用consul來做服務管理中心。consul是採用golang開發的,cap中滿足cp的一款服務管理系統。選擇它的原因就是它足...