從零學springCloud系列(一):註冊中心Eureka詳解

一、Spring Cloud Eureka簡介

Spring Cloud Eureka是Spring Cloud Netflix微服務套件中的一部分,它基於Netflix Eureka做了二次封裝,主要完成微服務架構中的服務治理功能。Spring Cloud通過爲Eureka增加了Spring Boot 風格的自動化配置,我們只需要通過簡單的引入依賴和註解配置就能讓Spring Boot構建的微服務應用輕鬆地與Eureka服務治理提醒進行整合。

Eureka服務端,我們也稱爲服務註冊中心,它同其他服務註冊中心一樣,支持高可用配置。它依託於強一致性提供良好的服務實例可用性,可以應對多種不同的故障場景。如果Eureka以集羣模式部署,當集羣中有分片出現故障時,那麼Eureka就轉入自我保護模式。它允許在分片故障的期間繼續提供服務的發現和註冊,當故障分片恢復運行時集羣中的其他分片會把它們的狀態再次同步回來。以AWS上的實踐爲例,Netflix推薦每個可用的區域運行一個Eureka服務端,通過它來形成集羣。不同可用區域的服務註冊中心通過異步模式互相複製各自的狀態,這意味着在任意給定的時間點每個實例關於所有服務的狀態是有細微差別的。

  Eureka客服端,主要處理服務的註冊與發現。客戶端服務通過註解和參數配置的方式,嵌入在客戶端應用程序的代碼中,在應用程序運行時,Eureka客戶端向註冊中心註冊自身提供的服務並定期性的發送心跳來更新它的服務租約。同時,它也能從服務端查詢當前註冊的服務信息並把它們緩存到本地並週期性的刷新服務狀態。
 

二、Eureka服務治理體系詳解

Eureka服務治理 體系主要包括三個角色:服務註冊中心、服務提供者以及服務消費者。

基礎架構

在Eureka整個服務治理架構中包含了三個核心要素:

  • 服務註冊中心:Eureka提供的服務端,主要提供服務註冊於發現功能。
  • 服務提供者:提供服務的應用,可以使Spring Boot應用,可以使其他技術平臺且遵循Eureka通信機制應用。它將自己提供的服務註冊到Eureka,以供其他 應用發現。
  • 服務消費者:消費者應用從服務註冊中心獲取服務 列表,從而使消費者可以知道去何處調用其所需要的服務。

服務治理機制

通過上面圖解,我們進一步瞭解基於Eureka的服務治理中心是如何一步步運行起來的。

首先我們先來介紹上面圖中幾個關鍵的元素:

  •  服務註冊 中心-1和服務註冊中心-2,他們互相註冊中了高可用集羣。
  • 服務提供者啓動了兩個實例,一個註冊到 “服務註冊中心-1”上,另一個註冊到了服務註冊中心-2上面。
  • 還有兩個服務消費者,他們也都分別指向了一個註冊中心。

服務提供者

服務註冊

“服務提供者”在服務啓動是時候通過發送REST請求的方式將自己註冊到Eureka Server上面,同時攜帶了 自身的一些元數據,當Eureka Server接收到REST請求以後,將數據存儲在一個雙層結構的Map中,其中第一層是服務名稱,第二層是具體的服務實例名稱。

在服務註冊代碼中,我們需要確認一下 eureka.client.register-with-eureka=true參數是否正確,默認配置是true,如果配置成false將不會啓動註冊功能

服務同步

如上圖所示,兩個服務提供者分別註冊到不同的註冊中心,也就是說,他們的信息分別被兩個註冊中心所維護。此時,由於註冊中心之間也互相註冊爲服務,當服務提供者發送註冊請求到一個註冊中心的時候,它會將該請求轉發給集羣中心的其他註冊中心,從而實現註冊中心的服務同步。通過服務同步,兩個服務提供者的信息就可以通過任意一個註冊中心獲得。

服務續約

當服務註冊完成以後,服務提供者會維護一個心跳用來持續告訴Eureka Server:“我還活着”,以防止被Eureka的剔除任務從服務列表中剔除,我們稱該操作爲服務續約。

關於服務續約我們有兩個重要屬性,我們可以關注並根據需要進行調整:

   eureka.instance.lease-renewal-interval-in-seconds=30

   eureka.instance.lease-expiration-duration-in-seconds=90

  eureka.instance.lease-renewal-interval-in-seconds參數用於定義服務續約任務調用間隔時間,默認爲30秒。    eureka.instance.lease-expiration-duration-in-seconds參數用於定義服務失效的時間,默認爲90秒。


服務消費者

獲取服務

到這裏,在服務註冊中心已經註冊了一個服務,並且該服務有兩個實例。當我們 啓動服務消費者的 時候,他會發送一個REST請求給服務註冊中心,來獲取上面註冊的服務清單。爲了性能考慮,Eureka Server會維護一份只讀服務清單來返回客戶端,同時該緩存清單每個30秒更新一次。

獲取服務是服務消費者的基礎,所以必須確保eureka.client.fetch-registry=true參數沒有被修改成false,該值默認爲true。若希望修改緩存清單的更新時間,可以 通過eureka.client.rgistry-fetch-interval-seconds=30參數進行修改,該參數默認爲30,單位秒。

服務調用

服務消費者在獲取服務清單後,通過服務名可以獲得具體提供服務的實例名和該實例的元數據信息,因爲有這些服務實例的詳細信息,所以客戶端可以根據自己的需要決定具體調用哪個實例,在Ribbon中或默認採用輪詢的方式進行調用,從而實現客戶端的負載均衡。

對於訪問實例的選擇,Eureka中有Region和Zone的概念,一個Region中可以包含多個Zone,每個服務客戶端需要被註冊到一個Zone中,所以每個客戶端對應一個Region和一個Zone。在進行服務調用的時候,優先訪問同處一個Zone中的服務提供方,若訪問不到,就訪問其他的Zone。

服務下線

在系統運行的過程中必然會面臨關閉或者重啓服務的某個實例的情況,在服務關閉期間,我們自然不希望客戶端會繼續調用關閉了的實例。所以在客戶端程序中,當服務實例進行正常關閉的時候,他會觸發一個服務下線的REST請求給Eureka Server,告訴服務註冊中心:“我要下線了”。服務端在接受到請求以後,將該服務狀態設置爲下線(DWON),並把該下線事件傳播出去。

服務註冊中心

有些時候,我們的服務實例並不一定會正常下線,可以由於內存溢出、網絡故障等等原因使得服務不能正常工作,而服務註冊中心並未收到“服務下線”請求。爲了從服務列表中講這些無法提供服務的實例剔除,Eureka Server在啓動的時候會創建一個定時任務,默認每隔一段時間(默認爲60s)將當前清單中超時(默認90s)沒有續約的服務剔除出去。

自我保護

當我們在本地調試Eureka程序時,基本上都會遇到一個這樣的問題,在服務註冊中心的信息面板中出現類似下面的紅色警告信息:

實際上,該警告就是觸發了Eureka Server的自我保護機制。之前我們介紹過,服務註冊到Eureka Server之後,會維護一個心跳連接,告訴Eureka Server自己還活着。Eureka Server在運行期間,會統計心跳失敗的比例在15分鐘之內是否  低於85%,如果出現低於的情況,Eureka Server 會將當前的實例註冊信息保護起來,讓這些實例不會過期,儘可能保護這些註冊信息,但是,在這段保護期間內若實例出現問題, 那麼客戶端很容易拿到實際已經不存在的服務實例,會出現調用 失敗的情況,所以 客戶端必須要有容錯機制,比如可以使用請求重試、斷路器等機制。

由於本地調試很容易觸發Eureka Server的保護機制,這會使得註冊中心維護的服務實例不那麼準確。所以在本地進行開發的時候,可以使用eureka.server.enable-self-preservation=false參數來關閉自我保護機制,以確保註冊中心可以將不可用的實例正確剔除。

三、代碼實例

實例代碼地址:https://github.com/zhenghaoxiao/spring-cloud-in-action/tree/dev

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章