1. 程式人生 > >Spring Cloud Eureka(三):認識Eureka Server 與 Eureka Client

Spring Cloud Eureka(三):認識Eureka Server 與 Eureka Client

Spring Cloud Netflix 是什麼

This project provides Netflix OSS integrations for Spring Boot apps through autoconfiguration and binding to the Spring Environment and other Spring programming model idioms. With a few simple annotations you can quickly enable and configure the common patterns inside your application and build large distributed systems with battle-tested Netflix components. The patterns provided include Service Discovery (Eureka), Circuit Breaker (Hystrix), Intelligent Routing (Zuul) and Client Side Load Balancing (Ribbon).

Spring Cloud Netflix 基於 Spring Boot,集成了NetFlix OSS的一些元件,只需通過註解配置和Spring的簡單註解,就可以快速的啟用和配置NetFlix的元件實現分散式系統的構建。這些元件包含的功能有服務發現(Eureka),熔斷器(Hystrix),智慧路由(Zuul)以及客戶端的負載均衡器(Ribbon)

Spring Cloud Eureka 是什麼

Spring Cloud Eureka 是基於Spring Cloud Netflix 做了二次封裝,它主要負責完成各個微服務例項的自動化註冊和發現功能。 在這裡插入圖片描述

Spring Cloud Eureka 相關概念

在這裡插入圖片描述

服務提供者

1.服務註冊

When a client registers with Eureka, it provides meta-data about itself such as host and port, health indicator URL, home page etc. Eureka receives heartbeat messages from each instance belonging to a service. If the heartbeat fails over a configurable timetable, the instance is normally removed from the registry.

服務在啟動的時候會通過傳送REST請求的方式將自己註冊到Eureka Server上, 同時帶上了自身服務的一些元資料資訊。註冊中心Eureka Server通過與服務之間的心跳來保持通訊,當某個服務例項在超時時間內沒有與註冊中心保持會話,那麼該服務例項將會從註冊中心正常移除。

Eureka Server 接收到這個REST請求之後,將元資料資訊儲存在一個雙層結構Map中, 其中第一層的key是服務名, 第二層的key是具體服務的例項名。

2.服務同步

如架構圖中所示,這裡的兩個服務提供者分別註冊到了兩個不同的服務註冊中心上,它們的資訊分別被兩個服務註冊中心所維護。由於服務註冊中心之間因互相註冊為服務, 當服務提供者傳送註冊請求到一個服務註冊中心時, 它會將該請求轉發給叢集中相連的其他註冊中心, 從而實現註冊中心之間的服務同步。通過服務同步,兩個服務提供者的服務資訊就可以通過這兩臺服務註冊中心中的任意一臺獲取到。

3.服務續約

在註冊完服務之後,服務提供者會維護一個心跳用來保持與EurekaServer 的會話,以防止Eureka Server 的剔除任務將該服務例項從服務列表中移除掉,那麼這個心跳保持就叫做服務續約(Renew)。

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

服務續約任務的呼叫間隔時間,預設為30秒
eureka.instance.lease-renewal-interval-in-seconds=30

服務失效的時間,預設為90秒。
eureka.instance.lease-expiration-duration-in-seconds=90

服務消費者

1.獲取服務

當啟動服務消費者的時候,它會發送一個REST請求給服務註冊中心,來獲取上面註冊的服務列表。Eureka Server會維護一份只讀的服務列表來返回給客戶端,同時服務消費者會在本地快取服務列表的清單並每隔30秒更新一次。

獲取服務是服務消費者的基礎,所以必有兩個重要引數需要注意:

# 啟用服務消費者從註冊中心拉取服務列表的功能
eureka.client.fetch-registry=true

# 設定服務消費者從註冊中心拉取服務列表的間隔
eureka.client.registry-fetch-interval-seconds=30
2.服務呼叫

服務消費者在獲取服務清單後,通過服務名可以獲得具體提供服務的例項名和該例項的元資料資訊。因為有這些服務例項的詳細資訊, 所以客戶端可以根據自己的需要決定具體呼叫哪個例項,在ribbon中會預設採用輪詢的方式進行呼叫,從而實現客戶端的負載均衡。

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

3.服務下線

在客戶端程式中,當服務例項進行正常的關閉操作時,它會觸發一個服務下線的REST請求給Eureka Server, 告訴服務註冊中心自己要下線了。服務端在接收到請求之後,將該服務狀態置為下線(DOWN), 並把該下線事件傳播出去。

服務註冊中心

1.失效剔除

服務例項並不一定會正常下線,可能由於記憶體溢位、網路故障等原因使得服務不能正常工作,而服務註冊中心並未收到“服務下線” 的請求。為了從服務列表中將這些無法提供服務的例項剔除, Eureka Server在啟動的時候會建立一個定時任務,預設每隔一段時間(預設為60秒) 將當前清單中超時(預設為90秒)沒有續約的服務剔除出去。

2.自我保護機制

當我們在本地除錯基於Eureka的程式時, 基本上都會碰到這樣一個問題, 在服務註冊中心的資訊面板中出現類似下面的紅色警告資訊:

EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY'RE NOT. RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPIRED JUST TO BE SAFE.

在這裡插入圖片描述

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

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