SpringCloud升級之路2020.0.x版-19.Eureka的服務端設計與配置
- 2021 年 8 月 24 日
- 筆記
- Spring Cloud, Spring Cloud 升級之路
本系列代碼地址://github.com/HashZhang/spring-cloud-scaffold/tree/master/spring-cloud-iiford
Eureka Server 配置是 Eureka Server 需要的一些配置,包括之前多次提到的定時檢查實例過期的配置,自我保護相關的配置,同一 zone 內集群相關的配置和跨 zone 相關的配置。在 Spring Cloud 中,Eureka 客戶端配置以 eureka.server
開頭,對應配置類為 EurekaServerConfigBean
根據上一節 Eureka 客戶端分析,我們知道 Eureka 客戶端主要訪問如下幾個接口:
- 註冊:
POST /eureka/apps/appID
- 心跳:
PUT /eureka/apps/appID/instanceID
- 獲取所有服務實例:
GET /eureka/apps
- 增量獲取所有服務實例:
GET /eureka/apps/delta
Eureka Server 處理這些請求的核心邏輯,以及相關配置如下圖所示:
實例註冊後需要發送心跳證明這個實例是活着的,Eureka Server 中也有定時任務檢查實例是否已經過期。
eureka:
server:
#主動檢查服務實例是否失效的任務執行間隔,默認是 60s
eviction-interval-timer-in-ms: 3000
#這個配置在兩個地方被使用:
#如果啟用用了自我保護,則會 renewal-threshold-update-interval-ms 指定的時間內,收到的心跳請求個數是否小於實例個數乘以這個 renewal-percent-threshold
#定時任務檢查過期實例,每次最多過期 1 - renewal-percent-threshold 這麼多比例的實例
renewal-percent-threshold: 0.85
服務器中有定時過期的任務,檢查遲遲沒有心跳的實例,並註銷他們。自我保護主要針對集群中網絡出現問題,導致有很多實例無法發送心跳導致很多實例狀態異常,但是實際實例還在正常工作的情況,不要讓這些實例不參與負載均衡。
eureka:
server:
#注意,最好所有的客戶端實例配置的心跳時間相關的配置,是相同的。這樣使用自我保護的特性最準確。
#關閉自我保護
#我們這裡不使用自我保護,因為:
#自我保護主要針對集群中網絡出現問題,導致有很多實例無法發送心跳導致很多實例狀態異常,但是實際實例還在正常工作的情況,不要讓這些實例不參與負載均衡
#啟用自我保護的情況下,就會停止對於實例的過期
#但是,如果出現這種情況,其實也代表很多實例無法讀取註冊中心了。
#並且還有一種情況就是,Eureka 重啟。雖然不常見,但是對於鏡像中其他的組件更新我們還是很頻繁的
#我傾向於從客戶端對於實例緩存機制來解決這個問題,如果返回實例列表為空,則使用上次的實例列表進行負載均衡,這樣既能解決 Eureka 重啟的情況,又能處理一些 Eureka 網絡隔離的情況
#自我保護模式基於每分鐘需要收到 renew (實例心跳)請求個數,如果啟用了自我保護模式,只有上一分鐘接收到的 renew 個數,大於這個值,實例過期才會被註銷
enable-self-preservation: false
# 每分鐘需要收到 renew (實例心跳)請求個數是需要動態刷新的,這個刷新間隔就是 renewal-threshold-update-interval-ms
#更新流程大概是:計算當前一共有多少實例,如果大於之前期望的實例量 * renewal-percent-threshold(或者沒開啟自我保護模式),則更新期望的實例數量為當前一共有多少實例
#之後根據期望的實例數量,計算期望需要收到的實例心跳請求個數 = 期望的實例數量 * (60 / expected-client-renewal-interval-seconds) * renewal-percent-threshold
#公式中 60 代表一分鐘,因為公式用到了 expected-client-renewal-interval-seconds,也就是實例平均心跳間隔,為了使這個公式準確,最好每個實例配置一樣的心跳時間
#默認 900000ms = 900s = 15min
renewal-threshold-update-interval-ms: 900000
#上面提到的實例平均心跳間隔,或者說是期望的心跳間隔,為了使這個公式準確,最好每個實例配置一樣的心跳時間
#默認 30s
expected-client-renewal-interval-seconds: 30
#這個配置在兩個地方被使用:
#如果啟用用了自我保護,則會 renewal-threshold-update-interval-ms 指定的時間內,收到的心跳請求個數是否小於實例個數乘以這個 renewal-percent-threshold
#定時任務檢查過期實例,每次最多過期 1 - renewal-percent-threshold 這麼多比例的實例
renewal-percent-threshold: 0.85
上面我們提到了,同一區域內的 Eureka 服務器實例,收到的客戶端請求,會轉發到同一區域內的的其他 Eureka 服務器實例。同時,在某一 Eureka 服務器實例啟動的時候,會從同一區域內其他 Eureka 服務器同步實例列表。並且,轉發到其他 Eureka 服務器實例是異步轉發的,這就有專門的線程池進行轉發。同時,轉發的也是 HTTP 請求,這就需要 HTTP 連接池:
eureka:
server:
#Eureka Server 從配置中更新同一區域內的其他 Eureka Server 實例列表間隔,默認10分鐘
peer-eureka-nodes-update-interval-ms: 600000
#啟動時從其他 Eureka Server 同步服務實例信息的最大重試次數,直到實例個數不為 0,默認為 0,這樣其實就是不同步
registry-sync-retries: 0
#啟動時從其他 Eureka Server 同步服務實例信息重試間隔
registry-sync-retry-wait-ms: 30000
#集群內至少有多少個 UP 的 Eureka Server 實例數量,當前 Eureka Server 狀態為 UP。默認 -1,也就是 Eureka Server 狀態不考慮 UP 的集群內其他 Eureka Server 數量。
min-available-instances-for-peer-replication: -1
#請求其他實例任務的最大超時時間,默認 30 秒
max-time-for-replication: 30000
#用來處理同步任務的線程數量,有兩個線程池,一個處理批量同步任務,默認大小為20
max-threads-for-peer-replication: 20
#另一個處理非批量任務(如果沒用 AWS Autoscaling 對接相關特性則沒有啥用),默認大小為20
max-threads-for-status-replication: 20
#處理批量任務的線程池隊列長度,默認為 10000
max-elements-in-peer-replication-pool: 10000
#處理非批量任務的線程池隊列長度,默認為 10000
max-elements-in-status-replication-pool: 10000
#Eureka Server 通過 httpclient 訪問其他 Eureka Server 同步實例,httpclient 的連接超時,默認 200ms
peer-node-connect-timeout-ms: 200
#httpclient 的讀取超時,默認 200ms,一般不用太長
peer-node-read-timeout-ms: 200
#httpclient 的最大總連接數量,默認 1000
peer-node-total-connections: 1000
#httpclient 的對於某一 host 最大總連接數量,默認 500
peer-node-total-connections-per-host: 500
#httpclient 的連接空閑保持時間,默認 30s
peer-node-connection-idle-timeout-seconds: 30
Eureka 服務器會定時拉取其他區域的服務實例列表緩存在本地。在查詢本地查詢不到某個微服務的時候,就會查詢這個遠程區域服務實例的緩存。相關配置如下:
eureka:
server:
#請求其他 Region 的 httpclient 的連接超時,默認 1000ms
remote-region-connect-timeout-ms: 1000
#請求其他 Region 的 httpclient 的讀取超時,默認 1000ms
remote-region-read-timeout-ms: 1000
#請求其他 Region 的 httpclient 的最大總連接數量,默認 1000
remote-region-total-connections: 1000
#請求其他 Region 的 httpclient 的對於某一 host 最大總連接數量,默認 500
remote-region-total-connections-per-host: 500
#請求其他 Region 的 httpclient 的連接空閑保持時間,默認 30s
remote-region-connection-idle-timeout-seconds: 30
#請求其他 Region 的 http 請求是否開啟 gzip,對於其他 Region 我們認為網絡連接是比較慢的,所以默認開啟壓縮
g-zip-content-from-remote-region: true
# remote-region-urls-with-name:
# region2eureka1: //127:0:0:1:8212/eureka/
# region2eureka2: //127:0:0:1:8213/eureka/
# remote-region-app-whitelist:
#如果需要從其他 Region 獲取實例信息,這個獲取間隔,默認為 30s
remote-region-registry-fetch-interval: 30
#如果需要從其他 Region 獲取實例信息,這個任務的線程池,默認為 20個
remote-region-fetch-thread-pool-size: 20
Eureka 服務實例信息緩存配置
Eureka Server 在內存中存儲所有服務實例信息,並且對於響應做了多層緩存。
eureka:
server:
# 增量實例隊列實例過期時間,默認 3 分鐘
retention-time-in-m-s-in-delta-queue: 180000
# 增量實例隊列過期任務間隔,默認 30s
delta-retention-timer-interval-in-ms: 30000
# 響應緩存中有兩個主要元素,一個是 readOnlyCacheMap,另一個是 readWriteCacheMap
# 是否使用 readOnlyCacheMap,默認為 true
# 如果為是,則從 readOnlyCacheMap 讀取,否則直接讀取 readWriteCacheMap
use-readonly-response-cahce: true
# 初始 readWriteCacheMap 大小,默認 1000
initial-capacity-of-response-cache: 1000
# LoadingCache 緩存過期時間,默認 180s
response-cache-auto-expiration-in-seconds: 9
# 定時從 LoadingCache 同步到只讀緩存的間隔時間,默認為 30s
response-cache-update-interval-ms: 3000
我們這一節詳細分析了 Eureka Server 相關的配置。下一節,我們將給大家提供一個配置模板,啟動一個 Eureka Server 集群。
微信搜索「我的編程喵」關注公眾號,每日一刷,輕鬆提升技術,斬獲各種offer: