1. 程式人生 > >Spring Cloud系列教程 | 第三篇:Eureka心跳健康檢查機制

Spring Cloud系列教程 | 第三篇:Eureka心跳健康檢查機制

推薦 Spring Cloud 視訊:

Eureka心跳健康檢查機制

執行階段執行健康檢查的目的是為了從Eureka伺服器登錄檔中識別並刪除不可訪問的微服務,Eureka 伺服器並不是向客戶端傳送心跳請求,而是反過來,Eureka 客戶端將心跳傳送到Eureka伺服器,讓伺服器瞭解其狀態。

這些心跳機制就需要在微服務嵌入一個客戶端,用來發送心跳,但是客戶端本身必須確定其健康狀態,而且Eureka伺服器必須為客戶端公開一些REST操作以讓其釋出心跳。

Eureka伺服器向客戶端公開下面資源以讓其傳送心跳:

PUT /eureka/apps/{app id}/{instance id}?status={status}

{instance id}採用 hostname:app id:port,其中app id代表標識唯一的Eureka客戶端例項,Eureka伺服器會識別一些狀態數值:UP; DOWN; STARTING; OUT_OF_SERVICE; UNKNOWN.

客戶端傳送心跳時的URL如下:

PUT /eureka/apps/ORDER-SERVICE/localhost:order-service:8886?status=UP

Eureka伺服器收到心跳請求後,會續訂該例項的租約。如果是第一個心跳,則Eureka伺服器以404響應,之後客戶端必須首先發送註冊請求。

此外, Eureka伺服器公開以下操作以允許健康狀態的修改和刪除:

PUT /eureka/apps/{app id}/{instance id}/status?value={status}

DELETE /eureka/apps/{app id}/{instance id}/status

修改操作(即PUT上面的操作)是用於手動獲取健康的例項OUT_OF_SERVICE時操作,或者使用Asgard等管理工具 (暫時禁止某些例項的流量)時操作。

這種修改操作對於“紅/黑”部署非常有用,在這種情況下,你可以在一段時間內執行較舊版本的微服務(如果新版本不穩定,則可以輕鬆回滾到舊版本)。完成新版本的部署並且新版本開始為請求提供服務後,可以讓舊版本OUT_OF_SERVICE(但不會讓他們停止)暫停提供請求服務。即

PUT /eureka/apps/ORDER-SERVICE/localhost:order-service:8886/statusvalue=OUT_OF_SERVICE

上面修改的狀態也可以被丟棄,我們可以指示讓Eureka伺服器開始遵守例項本身釋出的狀態,如下所示:

DELETE /eureka/apps/ORDER-SERVICE/localhost:order-service:8886/status

當您發現微服務的新版本不穩定並且您希望獲得舊版本(即已經被打上OUT_OF_SERVICE標記的版本)以開始提供請求時,上述辦法非常有用。

Eureka客戶端自我診斷

Eureka客戶端(或伺服器)都是不呼叫/health端點來確定例項的健康狀態,Eureka例項的執行狀況由HealthCheckHandler實現確定,只要應用程式正在執行,預設情況下HealthCheckHandler始終會通知應用程式處於某種 UP 狀態。

Eureka允許通過EurekaClient#registerHealthCheck()API 插入自定義的HealthCheckHandlers,如果在Spring Cloud設定了以下屬性,則會註冊一個新的Spring自己的處理程式EurekaHealthCheckHandler:

eureka.client.healthcheck.enabled=true

該EurekaHealthCheckHandler彙總了多個健康指標,如健康狀況:

DiskSpaceHealthIndicator
RefreshScopeHealthIndicator
HystrixHealthIndicator
它將這些狀態會對映到Eureka支援的狀態之一,之後被對映後的狀態將通過心跳傳播到Eureka伺服器。

Eureka客戶端健康端點

Eureka客戶端在向伺服器註冊時會在其POST的內容中加入healthCheckUrl ,這個healthCheckUrl的值是由以下例項屬性計算得出:
eureka.instance.health-check-url
eureka.instance.health-check-url-path

.health-check-url-path的預設值是 /health,這是Springboot預設專門用於檢查健康的actuator端點,除非.heath-check-url被專門配置了。

如果實現自定義健康狀況端點或更改預設健康檢查路徑,則應配置這些屬性:

  • 如果更改預設健康端點;
endpoints.health.path=/new-heath
# either relative path
eureka.instance.health-check-url-path=${endpoints.health.path}
# or absolute path
eureka.instance.health-check-url=http://${eureka.hostname}:${server.port}/${endpoints.health.path}

  • 如果你引入一個 management.context-path
management.context-path=/admin
# either relative path
eureka.instance.health-check-url-path=${management.context-path}/health
# or absolute path
eureka.instance.health-check-url=http://${eureka.hostname}:${server.port}/${management.context-path}/health

健康狀況的試驗

Eureka伺服器並不關心客戶端的狀態 - 它只記錄客戶端狀態,當有人查詢其登錄檔時,它也會發布客戶的健康狀況。即

GET /eureka/apps/ORDER-SERVICE

<application>
  <name>DISCOVERY-EUREKA-CLIENT</name>
  <instance>
     <instanceId>localhost:discovery-eureka-client:8886</instanceId>
     <ipAddr>192.168.1.6</ipAddr>
     <port>8886</port>
     <status>UP</status>
     <overriddenstatus>UP</overriddenstatus>
     <healthCheckUrl>http://localhost:8886/health</healthCheckUrl>
     ...
     ...
  </instance>
</application>

這個響應有三個與健康有關的重要資訊: status 、overridenstatus和healthCheckUrl

status 是Eureka例項本身釋出的健康狀況。
overriddenstatus 是手動或通過工具強制執行的健康狀態。比如PUT /eureka/apps/{app id}/instance id}/status?value={status}操作用於修改釋出的狀態,那麼status和overriddenstatus都將變更為新的狀態。
healthCheckUrl 是客戶端公開GET其健康狀態的端點。
其他工具則可以利用這些健康資訊:

客戶端負載平衡器(如Ribbon)可以做出負載平衡決策 : Ribbon 讀取 status 屬性並僅使用具有UP 負載平衡狀態的例項 。但是,Ribbon不會呼叫 healthCheckUrl, 而是依賴於登錄檔中可用的、已釋出例項狀態。

像Asgard這樣的部署工具可以做出部署決策 - 在滾動部署期間,Asgard部署了一個新版本的微服務,在 部署其餘例項之前一直等待當前例項轉換到UP 狀態。但是,status Asgard 不是依賴於登錄檔中可用的例項狀態(即屬性),而是 通過呼叫 healthCheckUrl來了解例項狀態 ,這可能是因為status 屬性的值可能會變得陳舊(因為它取決於下一節中描述的幾個因素),但在這種情況下,實時健康狀態很重要,以避免部署延遲。

健康狀況的準確性

由於下面列出的原因,Eureka伺服器登錄檔健康狀況的並不總是準確的。

  • CAP中的AP - 由於Eureka在CAP定理方面定位於高度可用的系統,因此在網路分割槽期間,叢集Eureka伺服器之間的資訊可能不一致。
  • 伺服器響應快取 - Eureka伺服器維護一個響應快取,預設情況下每30秒更新一次。因此,實際上在 GET /eureka/apps/{app id}/ 響應中出現 UP 的例項可能已經DOWN 了 。
  • 定期排程心跳 - 由於客戶端預設情況下每30秒傳送一次心跳,因此伺服器登錄檔中例項的執行狀況可能不準確。
  • 自我保護 - 當Eureka伺服器沒有收到超過某個閾值的心跳時,它會停止失效登錄檔中的客戶端,從而會使登錄檔不準確。

因此,客戶端應遵循適當的故障轉移機制來補充這種不準確性。

專家推薦

“隨著微服務架構的發展,Spring Cloud 使用得越來越廣泛。馳狼課堂http://www.chilangedu.com (QQ群:348039381) Spring Boot 快速入門,Spring Boot 與Spring Cloud 整合,docker+k8s,大型電商商城等多套免費實戰教程可以幫您真正做到快速上手,將技術點切實運用到微服務專案中。”

關注公眾號,每天精彩內容,第一時間送達!
在這裡插入圖片描述