一、開啟Eureka自我保護模式
訪問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.
那么表明Eureka的自我保護模式是啟動的。
解決這種情況的方法主要有幾種方式:
1. 等待 Eureka Server 自動恢復
正常的情況下,等待網絡恢復(或者沒有頻繁的啟動與關閉實例)后,等待一段時間 Eureka Server 會自動關閉自我保護模式,但是如果它遲遲沒有關閉該模式,那么便可以嘗試手動關閉,如下。
2. 重啟 Eureka Server
通常而言,PRD 環境建議對 Eureka Server 做負載均衡,這樣在依次關閉並開啟 Eureka Server 后,無效的實例會被清除,並且不會對正常的使用照成影響。
3. 關閉 Eureka 的自我保護模式
后面介紹
二、Eureka自我保護模式原理
默認情況下,如果在15分鍾內超過85%的客戶端節點都沒有正常的心跳,那么Eureka就認為客戶端與注冊中心出現了網絡故障(比如網絡故障或頻繁的啟動關閉客戶端),Eureka Server自動進入自我保護模式。不再剔除任何服務,當網絡故障恢復后,該節點自動退出自我保護模式。
eureka:
server:
#自我保護模式,當出現網絡分區故障、頻繁的開啟關閉客戶端、eureka在短時間內丟失過多客戶端時,會進入自我保護模式,即一個服務長時間沒有發送心跳,eureka也不會將其刪除,默認為true
enable-self-preservation: true
#eureka server清理無效節點的時間間隔,默認60000毫秒,即60秒
eviction-interval-timer-in-ms: 60000
#閾值更新的時間間隔,單位為毫秒,默認為15 * 60 * 1000
renewal-threshold-update-interval-ms: 15 * 60 * 1000
#閾值因子,默認是0.85,如果閾值比最小值大,則自我保護模式開啟
renewal-percent-threshold: 0.85
#清理任務程序被喚醒的時間間隔,清理過期的增量信息,單位為毫秒,默認為30 * 1000
delta-retention-timer-interval-in-ms: 30000
自我保護模式是一種對網絡異常的安全保護措施。使用自我保護模式讓Eureka集群更加的健壯、穩定。
三、關閉 Eureka 的自我保護模式
可以使用eureka.server.enable-self-preservation=false來禁用自我保護模式,適合在開發/測試環境中使用,生產環境建議打開自我保護模式。
對於開發/測試環境的 Eureka Server,個人更建議關閉它的自我保護模式,因為你可能需要不斷的開啟與關閉實例,如果並未關閉自我保護模式,那么很容易就會觸發自我保護模式,此時對調試會相對比較麻煩。
但是關閉自我保護模式,會有另外一個可能的問題,即隔一段時間后,可能會發生實例並未關閉,卻無法通過網關訪問了,此時很可能是由於網絡問題,導致實例(或網關)與 Eureka Server 斷開了連接,Eureka Server 已經將其注銷(網絡恢復后,實例並不會再次注冊),此時重啟 Eureka Server 節點或實例,並等待一小段時間即可。
關閉自我保護模式,可以在服務端和客戶端配置。
服務端配置:
eureka:
server:
enable-self-preservation: false
#eureka server清理無效節點的時間間隔,默認60000毫秒,即60秒
eviction-interval-timer-in-ms: 60000 # 單位毫秒
客戶端配置:
# 心跳檢測檢測與續約時間
# 測試時將值設置設置小些,保證服務關閉后注冊中心能及時踢出服務
eureka:
instance:
lease-renewal-interval-in-seconds: 1
lease-expiration-duration-in-seconds: 2
配置說明
lease-renewal-interval-in-seconds 每間隔1s,向服務端發送一次心跳,證明自己依然”存活“。 lease-expiration-duration-in-seconds 告訴服務端,如果我2s之內沒有給你發心跳,就代表我“死”了,請將我踢掉。
四、Eureka的健康檢查
說明:在Status欄顯示着UP,表示應用程序狀態正常。其它取值DOWN、OUT_OF_SERVICE、UNKNOWN等,只有UP的微服務會被請求。
由於Eureka Server與Eureka Client之間使用心跳機制來確定Eureka Client的狀態,默認情況下,服務器端與客戶端的心跳保持正常,應用程序就會始終保持“UP”狀態,所以微服務的UP並不能完全反應應用程序的狀態。
Spring Boot Actuator提供了/health端點,該端點可展示應用程序的健康信息,只有將該端點中的健康狀態傳播到Eureka Server就可以了,實現這點很簡單,只需為微服務配置如下內容:
#開啟健康檢查(需要spring-boot-starter-actuator依賴)
eureka.client.healthcheck.enabled = true
如果需要更細粒度健康檢查,可實現com.netflix.appinfo.HealthCheckHandler接口 。 EurekaHealthCheckHandler 已實現了該接口