Eureka自我保護機制
我們在使用Eureka的時候(尤其是做實驗測試的時候)經常會看到Eureka界面冒出來這樣一段紅色的警示語句
中文翻譯如下:
緊急情況!尤里卡可能不正確地聲稱實例在不在的情況下出現。續訂小於閾值,因此不會爲了安全而過期實例。
出現這種情況的解釋說明是:當前Eureka進入了自我保護模式
其中官方解釋是這樣的:
自我保護模式正是一種針對網絡異常波動的安全保護措施,使用自我保護模式能使Eureka集羣更加的健壯、穩定的運行。
那很好奇的是怎麼才能進入到這個狀態呢,衆所周知的Eureka註冊中心最主要的作用就是將我們一個個的微服務集中話管理供別人調用,我們在將服務註冊到我們的註冊中心的時候,Eureka Client會向Eureka Server(服務中心)發送第一次心跳,會將服務的實例信息註冊到註冊中心
Eureka Client 每30秒來發送一次心跳來更新實例信息。通知Eureka Server該實例仍然存在(也就是該能正常的提供服務)。如果超過90秒沒有發送更新(有可能是服務關閉或者網絡異常情況),則服務器將從註冊信息中將此服務移除。
關鍵是最後一句話:
如果Eureka Server在一定時間內(默認90秒)沒有接收到某個微服務實例的心跳,Eureka Server將會移除該實例
牛頓說過:沒有人能保證網絡一直能ping的通,所以問題產生了:
- 微服務能正常運行
- 微服務與Eureka Server之間無法正常通信(心跳不通)
上述的條件1和條件2就構成了一個悖論,現實是不應該在Eureka註冊中心刪除這一個能夠正常工作的微服務
這個情況下Eureka爲了防止誤殺情況產生,就自己進入了自我保護機制
定義:
如果在15分鐘內超過85%的客戶端節點都沒有正常的心跳,那麼Eureka就認爲客戶端與註冊中心出現了網絡故障,Eureka Server自動進入自我保護機制
在進入這個自我保護機制的時候我們來看一下我們Eureka頭部的System Status的描述是這樣的:
重點看紅色區域位置的三個參數(測試的時候其實只啓用了一臺Eureka註冊中心,一個服務實例Eureka Client也沒有…)
- Lease expiration enabled //租約到期已啓用
- Renews threshold //更新閾值
- Renews (last min) //更新(最後一分)
Lease expiration enabled的含義是是否啓用租約過期 ,當期關閉時該值默認是true, 自我保護機制開啓之後爲false
如果心跳失敗比例在 15 分鐘之內低於 85% 這個時候就會觸發 Eureka 的保護機制,但是開啓了保護機制,則服務註冊中心維護的服務實例就不是那麼準確了,此時我們可以使用eureka.server.enable-self-preservation=false來關閉保護機制,這樣可以確保註冊中心中不可用的實例被及時的剔除。
eureka:
server:
enable-self-preservation: false //關閉自我保護機制
重啓我們Eureka服務,我們會在頁面上看到:
THE SELF PRESERVATION MODE IS TURNED OFF. THIS MAY NOT PROTECT
INSTANCE EXPIRY IN CASE OF NETWORK/OTHER PROBLEMS.
翻譯爲:
自動保存模式關閉。這可能無法在出現網絡/其他問題時保護實例到期。
可以看到官方都不是很推薦這種情況的發生
剛纔我們在規則中看到兩個非常重要的時間30s和90s,他們的含義是
Eureka Client 每30秒來發送一次心跳來更新實例信息。通知Eureka Server該實例仍然存在(也就是該能正常的提供服務)。如果超過90秒沒有發送更新(有可能是服務關閉或者網絡異常情況),則服務器將從註冊信息中將此服務移除。
也就是說美國30s服務提供者需要向Eureka註冊中心通知一聲:我能正常使用,但是如果90S內沒有發送這種能正常使用的同坐,那麼Eureka註冊中心就會認爲你出了問題,當然這兩個時間也是可以在代碼中手工調整的,如下:
eureka:
server:
enable-self-preservation: false
instance:
hostname: localhost # Eureka註冊服務器名稱
lease-expiration-duration-in-seconds: 10 #默認90秒
lease-renewal-interval-in-seconds: 10 #默認30秒
最後強調:以上所有設置,最好都是用默認值