javascript
Spring Cloud Eureka 自我保护机制
Spring Cloud Eureka 自我保護機制
Eureka Server 在運行期間會去統計心跳失敗比例在 15 分鐘之內是否低于 85%,如果低于 85%,Eureka Server 會將這些實例保護起來,讓這些實例不會過期,但是在保護期內如果服務剛好這個服務提供者非正常下線了,此時服務消費者就會拿到一個無效的服務實例,此時會調用失敗,對于這個問題需要服務消費者端要有一些容錯機制,如重試,斷路器等。
我們在單機測試的時候很容易滿足心跳失敗比例在 15 分鐘之內低于 85%,這個時候就會觸發 Eureka 的保護機制,一旦開啟了保護機制,則服務注冊中心維護的服務實例就不是那么準確了,此時我們可以使用eureka.server.enable-self-preservation=false來關閉保護機制,這樣可以確保注冊中心中不可用的實例被及時的剔除(不推薦)。
自我保護模式被激活的條件是:在 1 分鐘后,Renews (last min) < Renews threshold。
這兩個參數的意思:
Renews threshold:Eureka Server 期望每分鐘收到客戶端實例續約的總數。
Renews (last min):Eureka Server 最后 1 分鐘收到客戶端實例續約的總數。
具體的值,我們可
以在 Eureka Server 界面可以看到:可以看到,我們部署了 3 個 Eureka Server(自注冊模式),另外,又部署 7 個服務,注冊到 Eureka Server 集群,參數值分別為:
Renews threshold:17
Renews (last min):20
下面說下Renews threshold和Renews threshold具體計算方式。
Renews threshold 計算代碼:
this.expectedNumberOfRenewsPerMin = count * 2; this.numberOfRenewsPerMinThreshold = (int) (this.expectedNumberOfRenewsPerMin * serverConfig.getRenewalPercentThreshold());count表示服務的數量,如果 Eureka Server 開啟自注冊模式,也算一個服務,比如我們上面的示例,count的值就是 10(3 個自注冊服務 + 7 個獨立服務),serverConfig.getRenewalPercentThreshold()默認是 0.85(可以通過eureka.server.renewal-percent-threshold配置)。
所以,根據上面的分析,我們可以計算出Renews threshold的值:(int)(10 * 2 * 0.85) = (int)17 = 17。
Renews (last min)計算方式:count * 2,數值 2 表示每 30 秒 1 個心跳,每分鐘 2 個心跳的固定頻率因子,所以具體值為:10 * 2 = 20。
如果在 1 分鐘后,Renews (last min) < Renews threshold,默認需等待 5 分鐘(可以通過eureka.server.wait-time-in-ms-when-sync-empty配置),即 5 分鐘后你會看到下面的提示信息:
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.server.enable-self-preservation設為false),不推薦。
降低renewalPercentThreshold的比例(eureka.server.renewal-percent-threshold設置為0.5以下,比如0.49),不推薦。
部署多個 Eureka Server 并開啟其客戶端行為(eureka.client.register-with-eureka不要設為false,默認為true),推薦。
Eureka 的自我保護模式是有意義的,該模式被激活后,它不會從注冊列表中剔除因長時間沒收到心跳導致租期過期的服務,而是等待修復,直到心跳恢復正常之后,它自動退出自我保護模式。這種模式旨在避免因網絡分區故障導致服務不可用的問題。例如,兩個客戶端實例 C1 和 C2 的連通性是良好的,但是由于網絡故障,C2 未能及時向 Eureka 發送心跳續約,這時候 Eureka 不能簡單的將 C2 從注冊表中剔除。因為如果剔除了,C1 就無法從 Eureka 服務器中獲取 C2 注冊的服務,但是這時候 C2 服務是可用的。
所以,Eureka 的自我保護模式最好還是開啟它。
Eureka Server 單機版配置示例:
debug: true spring:application:name: eureka-server logging:level:com.netflix.eureka: 'off'com.netflix.discovery: 'off' server:port: 8100 eureka:instance:hostname: localhostserver:enable-self-preservation: false #關閉自我保護機制client:register-with-eureka: falsefetch-registry: falseservice-url:defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/總結
以上是生活随笔為你收集整理的Spring Cloud Eureka 自我保护机制的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java-ThreadLocal三种使用
- 下一篇: Dubbo和SpringCloud的区别