Spring Cloud Eureka原理分析(三):註冊資訊讀取(服務端)

xinlmain發表於2018-12-19

服務端快取

服務端的註冊資訊讀取使用快取,而非直接讀取registry那個ConcurrentHashMap。快取的主要邏輯都在ResponseCacheImpl這個類中。

快取有兩層,第一層是Guava的帶生存時間的LoadingCache,稱為readWriteCacheMap;第二層是一個ConcurrentHashMap,稱為readOnlyCacheMap

參見下面的示意圖:

兩層cache

下面看一下圖中兩個重要的方法。

generatePayload(Key key)

此方法接受一個Key型別的引數,返回一個Value型別。 其中Key中重要的欄位有:

  • KeyType,表示payload文字格式,有JSON和XML兩種值。
  • EntityType,表示快取的型別,有Application, VIP, SVIP三種值。
  • entityName,表示快取的名稱,可能是單個應用名,也可能是ALL_APPSALL_APPS_DELTA

Value則有一個String型別的payload和一個byte陣列,表示gzip壓縮後的位元組。

generatePayload()中根據EntityTypeEntityName,會呼叫不同的方法獲取regitry中的資訊。

  • registry.getApplications(): 得到所有的應用註冊資訊,結果為Applications物件。
  • registry.getApplicationsDeltas():得到增量更新資訊。
  • registry.getApplication():得到單個應用資訊。
  • getApplicationsForVip:就是先得到所有的應用註冊資訊,然後提取出vipAddress符合請求的應用資訊。

vip和svip是什麼

在Spring Cloud Eureka中,這兩個設定變成了VirtualHostName和SecureVirtualHostName,應該是類似DNS名稱。

invalidate(String appName, ...)

傳入的為某個應用名,而實際上要讓以下快取失效:

  • 應用的快取
  • ALL_APPS快取
  • ALL_APPS_DELTA快取

定時重新整理readOnlyCache任務

行為很簡單,就是把readWriteMap拷貝到readOnlyMap(但只拷貝readOnlyCache中已有的key)。 任務執行頻率由eureka.server.responseCacheUpdateIntervalMs控制,預設為30秒。

另外,eureka.server.useReadOnlyResponseCache可以設定是否啟用readOnlyCache,預設啟用。

全量資訊與增量資訊

前文已述,generatePayload()方法根據entityNameALL_APPSALL_APPS_DELTA決定生成已註冊的全量資訊,還是增量資訊。

全量資訊

呼叫registry.getApplications(),最終就是從本地(也可能包含遠端)的registry中讀取所有註冊資訊,構造成Applications物件。

增量資訊

在前兩篇文章中,提到了registry的實現類有一個AbstractInstanceRegistry.recentlyChangedQueue佇列,儲存最近的租約變更記錄。在註冊、下線等操作時,會修改此佇列。

另外,還有一個定時任務專門對超過一定時長的記錄進行移除。定時任務的執行間隔由eureka.server.deltaRetentionTimerIntervalInMs控制;時長閾值由eureka.server.retentionTimeInMSInDeltaQueue控制。

客戶端獲取增量資訊,與本地快取合併後通服務端的全量資訊比較雜湊值(雜湊演算法有特別實現,主要根據註冊應用內容)。如果雜湊值不同,則增量獲取失敗,需要一次全量獲取。

相關文章