SpringCloud升級之路2020.0.x版-19.Eureka的服務端設計與配置

乾貨滿滿張雜湊發表於2021-08-24

本系列程式碼地址:https://github.com/HashZhang/spring-cloud-scaffold/tree/master/spring-cloud-iiford

image

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 處理這些請求的核心邏輯,以及相關配置如下圖所示:

image

image

例項註冊後需要傳送心跳證明這個例項是活著的,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

image

伺服器中有定時過期的任務,檢查遲遲沒有心跳的例項,並登出他們。自我保護主要針對叢集中網路出現問題,導致有很多例項無法傳送心跳導致很多例項狀態異常,但是實際例項還在正常工作的情況,不要讓這些例項不參與負載均衡。

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

image

上面我們提到了,同一區域內的 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

image

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: http://127:0:0:1:8212/eureka/
      #      region2eureka2: http://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

相關文章