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