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,大型電商商城等多套免費實戰教程可以幫您真正做到快速上手,將技術點切實運用到微服務專案中。”
關注公眾號,每天精彩內容,第一時間送達!