1. 程式人生 > >Spring Cloud之Eureka自我保護環境搭建

Spring Cloud之Eureka自我保護環境搭建

Eureka詳解

 

服務消費者模式

 

獲取服務

 消費者啟動的時候,使用服務別名,會發送一個rest請求到服務註冊中心獲取對應的服務資訊,讓後會快取到本地jvm客戶端中,同時客戶端每隔30秒從伺服器上更新一次。

可以通過 fetch-inte vall-seconds=30引數進行修以通過eureka.client .registry該引數預設值為30, 單位為秒。

 

 

 

服務下線

    在系統執行過程中必然會面臨關閉或重啟服務的某個例項的情況,在服務關閉期有我們自然不希望客戶端會繼續呼叫關閉了的例項。所以在客戶端程式中,當服務例項過正常的關閉操作時,它會觸發一個服務下線的REST請求給Eureka Server, 告訴服務日中心:“我要下線了”。服務端在接收到請求之後,將該服務狀態置為下線(DOWN),井該下線事件傳播出去。

 

服務註冊模式

 失效剔除

 有些時候,我們的服務例項並不一定會正常下線,可能由於記憶體溢位、網路故障氣因使得服務不能正常工作,而服務註冊中心並未收到“服務下線”的請求。為了從服務表中將這些無法提供服務的例項剔除,Eureka Server 在啟動的時候會建立一個定時任多預設每隔一一段時間(預設為60秒)將當前清單中超時(預設為90秒)沒有續約的服務除出去

 自我保護

 

 

預設情況下,EurekaClient會定時向EurekaServer端傳送心跳,如果EurekaServer在一定時間內沒有收到EurekaClient傳送的心跳,便會把該例項從註冊服務列表中剔除(預設是90秒),但是在短時間內丟失大量的例項心跳,這時候EurekaServer會開啟自我保護機制,Eureka不會踢出該服務。

 

產生的原因:

 

在開發測試時,需要頻繁地重啟微服務例項,但是我們很少會把eureka server一起重啟(因為在開發過程中不會修改eureka註冊中心),當一分鐘內收到的心跳數大量減少時,會觸發該保護機制。可以在eureka管理介面看到Renews threshold和Renews(last min),當後者(最後一分鐘收到的心跳數)小於前者(心跳閾值)的時候,觸發保護機制,會出現紅色的警告:

 

EMERGENCY!EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY'RE NOT.RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEGING EXPIRED JUST TO BE SAFE.

 

從警告中可以看到,eureka認為雖然收不到例項的心跳,但它認為例項還是健康的,eureka會保護這些例項,不會把它們從登錄檔中刪掉。

該保護機制的目的是避免網路連線故障,在發生網路故障時,微服務和註冊中心之間無法正常通訊,但服務本身是健康的,不應該登出該服務,如果eureka因網路故障而把微服務誤刪了,那即使網路恢復了,該微服務也不會重新註冊到eureka server了,因為只有在微服務啟動的時候才會發起註冊請求,後面只會傳送心跳和服務列表請求,這樣的話,該例項雖然是執行著,但永遠不會被其它服務所感知。所以,eureka server在短時間內丟失過多的客戶端心跳時,會進入自我保護模式,該模式下,eureka會保護登錄檔中的資訊,不在登出任何微服務,當網路故障恢復後,eureka會自動退出保護模式。自我保護模式可以讓叢集更加健壯。

但是我們在開發測試階段,需要頻繁地重啟發布,如果觸發了保護機制,則舊的服務例項沒有被刪除,這時請求有可能跑到舊的例項中,而該例項已經關閉了,這就導致請求錯誤,影響開發測試。所以,在開發測試階段,我們可以把自我保護模式關閉,只需在eureka server配置檔案中加上如下配置即可:

 

 

 

但在生產環境,不會頻繁重啟,所以,一定要把自我保護機制開啟,否則網路一旦終端,就無法恢復。

當然關於自我保護還有很多個性化配置,這裡不詳細說明。

 

注意考慮網路不可達情況下:呼叫介面冪等、重試、補償等。 

 

 

Eureka自我保護機制:

 為了防止EurekaClient與EurekaServer網路不通的情況下,EurekaServer誤將EurekaClient服務剔除

所以,網路不通的情況下EurekaServer不會將EurekaClient服務剔除

 

當服務不可用時候,依然可以在Eureka可以查到服務的註冊資訊,呼叫者依然可以呼叫,但是會報錯

 

預設情況下:EurekaClient定時想EurekaSercer傳送心跳包,如果EurekaServer端,在一定時間(預設90s)內沒有收到對應心跳包,會直接從服務註冊列表剔除。短時間內,EurekaServe開啟自我保護機制,不會剔除該服務。

 

本地環境下,禁止自我保護機制。在Eureka的yml加入:

 server:
    # 測試時關閉自我保護機制,保證不可用服務及時踢出
    enable-self-preservation: false
    eviction-interval-timer-in-ms: 2000

  

服務提供者(Member)加入:

# 心跳檢測檢測與續約時間
# 測試時將值設定設定小些,保證服務關閉後註冊中心能及時踢出服務
  instance:
###Eureka客戶端向服務端傳送心跳的時間間隔,單位為秒(客戶端告訴服務端自己會按照該規則)    每隔1s傳送一次心跳包
    lease-renewal-interval-in-seconds: 1
####Eureka服務端在收到最後一次心跳之後等待的時間上限,單位為秒,超過則剔除(客戶端告訴服務端按照此規則等待自己)
    lease-expiration-duration-in-seconds: 2    

  

剔除掉之後,訪問也會報錯,因為本地有快取。預設30s時間去Eureka讀取一次新的服務列表

如果服務真的不可用了呢?真的宕機了掛了

本地呼叫重試,不行就輪訓到下一臺,保證網路介面冪等性,服務降級功能給客戶友好提示