[轉載] Eureka 的自我保護模式及相關問題
目錄
一、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的 自我保護模式(self-preservation mode) 被啟動了,當 Eureka Server 節點在短時間內丟失了過多例項的連線時(比如網路故障或頻繁的啟動關閉客戶端),那麼這個節點就會進入自我保護模式,一旦進入到該模式,Eureka server 就會保護服務登錄檔中的資訊,不再刪除服務登錄檔中的資料(即不會登出任何微服務),當網路故障恢復後,該 Ereaka Server 節點就會自動退出自我保護模式(我的 Eureka Server 已經幾個月了,至今未自動退出該模式)
預設情況下,如果 Ereaka Server 在一段時間內沒有接受到某個微服務示例的心跳,便會登出該例項(預設90秒),而一旦進入自我保護模式,那麼即使你關閉了指定例項,仍然會發現該 Ereaka Server 的註冊例項中會存在被關閉的例項資訊,如果你對該例項做了負載均衡,那麼僅關閉了其中一個例項,則通過閘道器呼叫介面api時很可能會發生如下異常:
{
"timestamp": 1507707671780,
"status": 500,
"error": "Internal Server Error",
"exception": "com.netflix.zuul.exception.ZuulException",
"message": "GENERAL"
}
解決這種情況的方法主要有幾種方式:
1. 等待 Eureka Server 自動恢復
正常的情況下,等待網路恢復(或者沒有頻繁的啟動與關閉例項)後,等待一段時間 Eureka Server 會自動關閉自我保護模式,但是如果它遲遲沒有關閉該模式,那麼便可以嘗試手動關閉,如下。
2. 重啟 Eureka Server
通常而言,PRD 環境建議對 Eureka Server 做負載均衡,這樣在依次關閉並開啟 Eureka Server 後,無效的例項會被清除,並且不會對正常的使用照成影響。
3. 關閉 Eureka 的自我保護模式
在yml配置檔案中新增如下配置:
eureka:
server:
enable-self-preservation: false
eviction-interval-timer-in-ms: 4000 # This is not required
從根源解決問題,但是並不推薦在PRD環境中使用,後面會說明。
二、開發環境的 Eureka Server
對於開發環境的 Eureka Server,個人更建議關閉它的自我保護模式,因為你可能需要不斷的開啟與關閉例項,如果並未關閉自我保護模式,那麼很容易就會觸發自我保護模式,此時對除錯會相對比較麻煩。
但是關閉自我保護模式,會有另外一個可能的問題,即隔一段時間後,可能會發生例項並未關閉,卻無法通過閘道器訪問了,此時很可能是由於網路問題,導致例項(或閘道器)與 Eureka Server 斷開了連線,Eureka Server 已經將其登出(網路恢復後,例項並不會再次註冊),此時重啟 Eureka Server 節點或例項,並等待一小段時間即可。
三、參考連結
https://github.com/Netflix/eureka/wiki/Understanding-Eureka-Peer-to-Peer-Communication
http://www.itmuch.com/spring-cloud-sum/understanding-eureka-self-preservation/
https://github.com/spring-cloud/spring-cloud-netflix/issues/2179
---------------------