微服務之服務註冊和發現的可行性方案

flynike發表於2021-09-09

在 中提到過,在雲原生、微服務時代,如果還是手動修改服務地址,是幾乎不可完成的工作,需要一種機制完成自動上報和獲取服務地址的支撐元件,可以保障服務的快速上線和下線,這就是服務註冊/發現元件。

為了表述方便,從系統規模定義幾個階段:

  • 巨型應用架構時期:很多應用都是一個巨型服務,一個應用包含所有功能,部署在小型機和大型機上,或者直接部署在物理伺服器上。
  • 單體架構時期:應用體量縮小,服務增多,而且出現虛擬化技術,物理伺服器被連線成虛擬化平臺,應用部署在虛擬機器中。
  • SOA架構時期:應用通用功能逐漸沉澱,業務應用藉助沉澱的通用元件逐漸解耦,微服務的很多元件也是從這個時期開始成型。
  • 微服務架構時期:這個時期承接模組化時期,甚至有一種說法是微服務只是SOA的一種特殊形式。系統進一步解耦,根據業務角色不同,應用以業務為分界,縮小為業務單元。
  • 函式架構時期:應用進一步分割為函式,實現serverless架構,不需要具體的伺服器概念,只需要執行函式的服務即可。目前來看,這個時期是比較理想的時期,因為不同人相互協作定義的函式,可能重複或者衝突,不利於架構的演進。

隨著大家對在微服務或者函式架構中趟坑,很多人開始提出迴歸單體應用架構,這應該也是架構螺旋進步的一種方式。

在微服務中,還有一種角色是根據呼叫關係定義的:

  • 客戶端服務(簡稱客戶端):呼叫其他服務的例項
  • 服務端服務(簡稱服務端):被其他服務例項呼叫的例項

微服務中客戶端和服務端只對一個呼叫定義的,客戶端在其他呼叫關係中,角色可能會轉變為服務端。

服務登錄檔

說到服務發現時,必須要說一個重要元件:服務登錄檔,它是服務發現的核心,是一個包含了所有服務例項的網路位置和監控狀態的資料庫,透過服務註冊元件將資訊寫入服務登錄檔,透過服務發現元件獲取有效的服務例項的網路位置資訊。目前常用的服務登錄檔有:Eureka、etcd、Consul、Zookeeper,Kibernetes等映象排程服務沒有明確的服務登錄檔元件,是透過內建的服務註冊功能實現。對於比如F5和Nginx這種代理器,其中的upstream配置也屬於服務登錄檔。

服務發現

在微服務架構中,服務之間透過輕量級協議互相呼叫,一般是HTTP請求,為了完成一次請求,服務需要知道目標服務例項的網路位置(IP和埠)。

在巨型應用架構時期,配置一個符合要求的伺服器環境需要花費大量的時間,也就意味著服務地址發生變動的機率和頻率都非常低,而且很多應用部署在一臺小型機或者大型機上。到了單體架構時期,應用體量大數量少,發生地址變動所需要修改的地方就比較少,所以對於服務發現也就沒有那麼強的需求。換句話說,在單體架構之前,服務例項的相對位置固定,變動頻率低,可以透過硬編碼到程式碼中。

但是到了雲時代,伺服器環境配置變得簡單,數量逐漸增多,擴充套件和遷移逐漸頻繁。而且,隨著虛擬化和容器的應用,伺服器地址都是根據規則動態分配,由於服務升級、擴充套件、失敗回滾等情況增多,服務的網路位置甚至不可預知。這個時候必須使用服務發現機制保證客戶端服務能夠自動獲取服務端服務的地址。

通常,服務發現有兩種模式:客戶端發現模式、服務端發現模式。

客戶端發現模式

客戶端發現模式透過客戶端元件根據負載均衡演算法決定相應服務例項的網路位置,也就是說,客戶端元件儲存有服務端所有例項的服務登錄檔,呼叫發生時,根據負載均衡演算法,從服務登錄檔中選擇一個網路位置,向服務端發起請求,完成呼叫。由於網路的不可靠性,有的客戶端元件還會實現訪問失敗重試、訪問超時時間設定等功能。

這種模式的架構如圖:

圖片描述

具體的過程為:

  1. 服務例項向服務註冊器上報網路位置,即註冊
  2. 客戶端服務發現元件定時拉取服務註冊器中服務例項的網路位置資訊及健康狀態,儲存在服務登錄檔中
  3. 客戶端服務呼叫服務端服務時,透過客戶端服務發現元件,根據負載均衡演算法,選取可用一個服務例項,發起呼叫

在Spring Cloud(或者說是Netflix開源元件)中,元件Eureka Server元件相當於服務註冊器,Eureka Client元件實現了服務登錄檔,Ribbon實現了負載均衡演算法和重試策略。

客戶端發現模式優缺點兼備。優點是對已有服務友好,除了客戶端元件外,其他部分無需改動。而且,客戶端存有所有服務例項資訊,可以有針對性的定義負載均衡演算法。缺點是客戶端與服務註冊器繫結,需要針對每種語言實現不同的客戶端元件。

服務端發現模式

服務端發現模式是有一個單獨的服務發現元件,這個例項持有服務登錄檔,同時也起到負載均衡器的作用,客戶端呼叫服務端時,直接呼叫服務發現例項,透過服務例項代理到後端服務例項中,所以服務端發現模式也被稱為代理模式

這種模式的架構如圖:

圖片描述

具體的過程為:

  1. 服務例項向服務註冊器上報網路位置,即註冊
  2. 服務發現例項定時透過某種機制獲取服務註冊器中服務例項的網路位置資訊及健康狀態,儲存在服務登錄檔中
  3. 客戶端服務呼叫服務端服務時,直接呼叫服務發現例項,服務發現例項根據內部實現,查詢服務登錄檔,將請求代理到後端服務例項

服務端發現模式中的服務發現元件有兩種實現方式:

  • 第一種,集中式代理,服務發現元件是單獨的服務例項,這個例項是高可用高吞吐的系統元件,代理後端服務例項,代表性的是F5和Nginx。
  • 第二種,主機程式代理,服務發現元件由系統環境提供,整合在主機上或者整合在作業系統中,代表性的是Istio ServiceMesh。

兩種實現方式的優點是語言無關,客戶端不需要關心任何服務發現的細節,只需要將原有的呼叫例項的請求修改為向服務發現例項傳送請求。集中式代理的缺點是,存在單點問題,需要單獨部署一個高可用、高吞吐的系統服務,由原來的一次呼叫增加為兩次呼叫,有效能開銷。主機程式代理的缺點是運維複雜,需要能力強的運維團隊做支援。

服務註冊

服務註冊是將服務例項的網路資訊和健康狀態寫入服務登錄檔中,有兩種方式:自注冊模式、第三方註冊模式。

自注冊模式

這種模式是服務例項主動向服務登錄檔上報網路位置和健康狀態,有的實現中,服務例項還會透過心跳保障註冊資訊不會過期。

圖片描述

Eureka就是採用的這種方式,服務例項透過Eureka Client元件主動上報自己的網路位置資訊和健康狀態。

這種模式實現相對簡單,但是把服務例項和服務登錄檔耦合,優缺點明顯。

第三方註冊模式

第三方註冊模式是服務例項不需要直接向服務登錄檔註冊資訊,而是藉助被稱為註冊器的元件進行註冊。服務註冊器是透過掃描部署環境或者訂閱事件的方式,跟蹤服務例項的變更。當監測到服務例項有變化,會向服務登錄檔上報變化資訊。

圖片描述

這種方式可以將服務例項與服務登錄檔解耦,同時也引入另外的問題。即註冊器需要內建在部署環境中,增加了運維複雜性。或者註冊器需要部署一個集中式的管理元件,成為系統約束點。

未完待續

在微服務中,服務例項的執行環境會動態變化,例項網路位置也是如此,因此,客戶端為了訪問服務必須要使用服務發現機制。

服務發現有客戶端發現模式和服務端發現模式,服務註冊有自注冊模式和第三方註冊模式。服務發現和服務註冊透過服務登錄檔連結在一起。

後面有時間,會再補充目前比較常用的服務發現、服務註冊的相關元件。


個人主頁:
個人博文:
CSDN主頁: https://blog.csdn.net/liuxinghao
CSDN博文:

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/2618/viewspace-2824852/,如需轉載,請註明出處,否則將追究法律責任。

相關文章