SpringCloud學習筆記【四】:Eureka的自我保護機制
Eureka的自我保護機制
本篇要點
- 介紹Eureka的自我保護機制。
- 介紹CAP原則。
- 介紹為什麼需要自我保護。
- 介紹如何禁止自我保護機制
Eureka的自我保護
保護模式主要用於一組客戶端和Eureka Server之間存在網路分割槽場景下的保護。一旦進入保護模式,Eureka Server將會嘗試保護其服務登錄檔中的資訊,不再刪除服務登錄檔中的資料,也就是不會登出任何微服務。
我們之前在註冊之後,強項停止某個微服務,就會出現下面這段紅字,此時就代表Eureka已經進入保護模式。
簡單來說:如果某個時刻某個微服務不可用了,Eureka不會立即對其進行清理,反而會依舊對該微服務資訊進行儲存。屬於分散式CAP原則的AP分支【可用性和分割槽容忍性】。
CAP是啥?
直接看看百度百科給出的解釋吧:
CAP原則又稱CAP定理,指的是在一個分散式系統中,一致性(Consistency)、可用性(Availability)、分割槽容錯性(Partition tolerance)。CAP 原則指的是,這三個要素最多隻能同時實現兩點,不可能三者兼顧。
-
一致性(C):在分散式系統中的所有資料備份,在同一時刻是否同樣的值。(等同於所有節點訪問同一份最新的資料副本)
-
可用性(A):在叢集中一部分節點故障
-
分割槽容忍性(P):以實際效果而言,分割槽相當於對通訊的時限要求。系統如果不能在時限內達成資料一致性,就意味著發生了分割槽的情況,必須就當前操作在C和A之間做出選擇。
CAP原則的精髓就是要麼AP,要麼CP,要麼AC,但是不存在CAP。如果在某個分散式系統中資料無副本, 那麼系統必然滿足強一致性條件, 因為只有獨一資料,不會出現資料不一致的情況,此時C和P兩要素具備,但是如果系統發生了網路分割槽狀況或者宕機,必然導致某些資料不可以訪問,此時可用性條件就不能被滿足,即在此情況下獲得了CP系統,但是CAP不可同時滿足。
為什麼會產生Eureka的自我保護機制
預設情況下,如果EurekaServer在一定時間內沒有收到某個微服務例項的心跳,EurekaServer將會登出該例項【預設90s】。但是當網路分割槽故障發生【延時、卡頓、擁擠】時候,微服務與EurekaServer之間無法正常通訊,以上行為可能變得非常危險了。
此時微服務本身其實是健康的,本不應該登出這個微服務,Eureka通過自我保護模式來解決這個問題:當EurekaServer節點在短時間內丟失過多客戶端時候(可能發生了網路分割槽故障),那麼這個節點就會進入自我保護模式了。
綜上:自我保護模式是一種應對網路異常的安全保護措施,它的涉及哲學就是寧可同時保留錯誤的服務註冊資訊,也不盲目登出任何可能健康的服務例項。老話反說就是:寧可放過三千,也不錯殺一個。自我保護模式讓Eureka叢集更加健壯穩定。
如何禁止自我保護
自我保護是可配置的,預設是開啟的,我們也可以通過配置禁止它,這裡演示一下如何禁止。
這一項配置由eureka.client.enable-self-preservation
決定,我們讓它變為false即可。
eureka.client.server.enable-self-preservation=false # 預設是true的
關閉之後,我們再次啟動server7001
,訪問localhost:7001
,出現以下警示:
表明註冊中心的自我保護模式已經成功關閉。
為了進行測試,我們使用單機版的Eureka環境,將cloud-eureka-server7001
的配置改為如下:
eureka:
instance:
hostname: eureka7001.com #eureka服務端的例項名稱
client:
register-with-eureka: false #false表示不向註冊中心註冊自己。
fetch-registry: false #false表示自己端就是註冊中心,我的職責就是維護服務例項,並不需要去檢索服務
service-url:
# 設定與Eureka Server互動的地址查詢服務和註冊服務都需要依賴這個地址
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
server:
#關閉自我保護機制,保證不可用服務被及時踢除
enable-self-preservation: false
# 清理增量佇列中過期的頻率
eviction-interval-timer-in-ms: 2000
- 關閉自我保護機制
enable-self-preservation
。 - 每2秒清理一次失效的服務:
eviction-interval-timer-in-ms
。
為了能更快地看到效果,將cloud-provider-payment8001
的配置也進行修改:
eureka:
client:
#表示是否將自己註冊進EurekaServer預設為true。
register-with-eureka: true
#是否從EurekaServer抓取已有的註冊資訊,預設為true。單節點無所謂,叢集必須設定為true才能配合ribbon使用負載均衡
fetchRegistry: true
service-url:
#單機版
defaultZone: http://localhost:7001/eureka
instance:
instance-id: payment8001
#訪問路徑可以顯示IP地址
prefer-ip-address: true
#Eureka客戶端向服務端傳送心跳的時間間隔,單位為秒(預設是30秒)
lease-renewal-interval-in-seconds: 1
#Eureka服務端在收到最後一次心跳後等待時間上限,單位為秒(預設是90秒),超時將剔除服務
lease-expiration-duration-in-seconds: 2
- 設定Eureka客戶端向服務端傳送心跳的時間間隔為1s。
- Eureka服務端在收到最後一次心跳後等待時間上限為2s。
接著我們先啟動7001,才啟動8001:
關閉8001:
此時,測試成功,一旦關閉自我保護模式,只要服務因為各種原因出現通訊異常,服務端不會再儲存他們的資訊,而是選擇剔除 。
原始碼下載
本系列文章為《尚矽谷SpringCloud教程》的學習筆記【版本稍微有些不同,後續遇到bug再做相關說明】,主要做一個長期的記錄,為以後學習的同學提供示例,程式碼同步更新到Gitee:https://gitee.com/tqbx/spring-cloud-learning,並且以標籤的形式詳細區分每個步驟,這個系列文章也會同步更新。