eureka緩存細節以及生產環境的最佳配置


eureka緩存細節以及生產環境的最佳配置

eureka作為spring cloud微服務架構里的注冊中心,是非常核心的一個組件,它避免了復雜的選主算法,架構比較簡單,搭個demo也確實很快,但是如果要用於生產環境,還是得注意很多東西,尤其是下線延遲…

服務獲取中的緩存問題

本節的內容都是從這個issue翻譯的:Documentation: changing Eureka renewal frequency WILL break the self-preservation feature of the server

為什么修改client的默認心跳時間,會導致自我保護模式失效?

Eureka Service會認為客戶端是以30s的頻率來發送心跳的。服務端期望收到的最大心跳時間是:
n instances x 2(60s/30s) x threshold

如果是2個實例,Eureka會期望每分鍾有:2 instances x 2 x 85% =3.4個心跳,也就是說需要3個心跳。
如果client的心跳改成15s,掛掉一個,另一個在1min內會發出4個心跳,而這時候的閾值還是3.4個,自我保護模式就失效了。
核心原因就是在Eureka Server計算期望心跳數的時候寫死了每分鍾的心跳間隔,即30秒,所以他永遠會是*2(感覺像是新手寫的代碼啊啊啊 -_-)

 

還有一個參數可以調整,eureka.server.renewalThresholdUpdateIntervalMs,心跳閾值重新計算的周期,默認15分鍾,可以改短一點,2min

 

客戶端首次注冊時間為什么要30s?如何改進?

首次注冊行為是和首次心跳綁定在一起的,首次心跳發送以后會收到not found的響應,client就知道還沒注冊過,client就會馬上注冊。首次心跳由參數
eureka.instance.leaseRenewalIntervalInSeconds控制的,默認30

可以通過eureka.client.initialInstanceInfoReplicationIntervalSeconds參數來加快首次注冊的速度。他是控制首次改變實例狀態(UP/DOWN )的時間,啟動的時候狀態肯定是需要改變的,所以他可以用來加快首次注冊速度,並且改變這個值不會影響到保護模式

另外如果你使用的是spring cloud eureka的話沒首次注冊延遲的問題,他會馬上注冊

其他影響快速獲取服務信息的因素

【服務端緩存】
因為服務端默認會有個read only response cache(下面會細說),每30秒更新一次(eureka.server.response-cache-update-interval-ms),所以可能注冊了不是馬上能看到(雖然通過rest api不能看到,但是你可以在web ui上看到,因為ui沒有緩存)

【客戶端緩存】
Eureka Client緩存的定期更新周期,他由eureka.client.registryFetchIntervalSeconds控制,默認30秒, 改成5秒

【Ribbon緩存】
如果你采用Ribbon來訪問服務,那么這里會有個緩存(他的數據來源是本地Eureka Client緩存),他由ribbon. ServerListRefreshInterval控制,默認30秒, 改成2秒

怎么更快的踢掉沒有心跳的機器

eureka.instance.leaseExpirationDurationInSeconds,這個值用來控制多久踢掉機器,默認是3個心跳周期,有點久,可以考慮改成2個,他不會影響到保護模式(如果開啟自我保護模式,心跳間隔因為上面的bug不能改,只能改這個了 -_-)


服務端緩存細節

Eureka內部的緩存分很多級,主要有registry、readWriterCacheMap、readOnlyCacheMap;另外還有一個維護最近180s增量的隊列recentlyChangedQueue

寫操作

包括注冊、取消注冊等,都直接操作在registry上,同時也會更新recentlyChangedQueue和readWriterCacheMap

讀操作

讀默認是從readOnlyCacheMap讀取,讀不到的話再從readWriterCacheMap,還沒有再從registry

濫用緩存的讀操作

這個讀操作的三級緩存結構,非常讓人困惑,registry已經是ConcurrentHashMap,純內存操作,性能非常高了,為什么前面還要加兩級緩存;readWriterCacheMap的數據是在寫入以后responseCacheAutoExpirationInSeconds(默認180)秒內失效,readOnlyCacheMap則是一個定時任務,每responseCacheUpdateIntervalMs(默認30)秒從readWriterCacheMap獲取最新數據

去掉readOnlyCacheMap

從CAP理論上看,Eureka是一個AP系統,但是在C層面這么弱,就是因為各種無謂的緩存造成的,看了下readWriterCacheMap去掉比較難,但是readOnlyCacheMap有一個開關useReadOnlyResponseCache,果斷關掉!!


Time Lag

最后再來看下Eureka wiki中提到的2min time lag問題,其實分多個角度看,不一定是2min

服務正常上線/修改,最大可能會有120s滯后

- 30(首次注冊 init registe) + 30(readOnlyCacheMap)+30(client fetch interval)+30(ribbon)=120
- 如果是在Spring Cloud環境下使用這些組件(Eureka, Ribbon),不會有首次注冊30秒延遲的問題,服務啟動后會馬上注冊,所以從注冊到發現,最多可能是90s。

服務異常下線:最大可能會有270s滯后

- 定時清理任務每eureka.server. evictionIntervalTimerInMs(默認60)執行一次清理任務
- 每次清理任務會把90秒(3個心跳周期,eureka.instance.leaseExpirationDurationInSeconds)沒收到心跳的踢除,但是根據官方的說法 ,因為代碼實現的bug,這個時間其實是兩倍,即180秒,也就是說如果一個客戶端因為網絡問題或者主機問題異常下線,可能會在180秒后才剔除
- 讀取端,因為readOnlyCacheMap以及客戶端緩存的存在,可能會在30(readOnlyCacheMap)+30(client fetch interval)+30(ribbon)=90
- 所以極端情況最終可能會是180+90=270

生產環境最佳配置

總結前面3點,經過梳理后,推薦的生產環境最佳配置如下:(可用於中小規模環境):

Eureka Server端配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
## 中小規模下,自我保護模式坑比好處多,所以關閉它
eureka.server.enableSelfPreservation=false
## 心跳閾值計算周期,如果開啟自我保護模式,可以改一下這個配置
## eureka.server.renewalThresholdUpdateIntervalMs=120000

## 主動失效檢測間隔,配置成5秒
eureka.server.evictionIntervalTimerInMs=5000

## 心跳間隔,5秒
eureka.instance.leaseRenewalIntervalInSeconds=5
## 沒有心跳的淘汰時間,10秒
eureka.instance.leaseExpirationDurationInSeconds=10

## 禁用readOnlyCacheMap
eureka.server. useReadOnlyResponseCache=false

服務提供者和clinet配置

## 心跳間隔,5秒
eureka.instance.leaseRenewalIntervalInSeconds=5
## 沒有心跳的淘汰時間,10秒
eureka.instance.leaseExpirationDurationInSeconds=10

# 定時刷新本地緩存時間
eureka.client.registryFetchIntervalSeconds=5
# ribbon緩存時間
ribbon.ServerListRefreshInterval=2000

改成上面配置后:

    • 正常上線下線客戶端最大感知時間:eureka.client.registryFetchIntervalSeconds+ribbon. ServerListRefreshInterval = 7秒

    • 異常下線客戶端最大感知時間:
      2*eureka.instance.leaseExpirationDurationInSeconds+
      eureka.server.evictionIntervalTimerInMs+
      eureka.client.registryFetchIntervalSeconds+
      ribbon. ServerListRefreshInterval = 3

 

 

一些參考:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM