服務端的註冊信息讀取使用緩存,而非直接讀取registry那個ConcurrentHashMap
。緩存的主要邏輯都在ResponseCacheImpl
這個類中。git
緩存有兩層,第一層是Guava的帶生存時間的LoadingCache
,稱爲readWriteCacheMap
;第二層是一個ConcurrentHashMap
,稱爲readOnlyCacheMap
。算法
參見下面的示意圖:數組
下面看一下圖中兩個重要的方法。緩存
此方法接受一個Key
類型的參數,返回一個Value
類型。 其中Key
中重要的字段有:app
KeyType
,表示payload文本格式,有JSON和XML兩種值。EntityType
,表示緩存的類型,有Application
, VIP
, SVIP
三種值。entityName
,表示緩存的名稱,多是單個應用名,也多是ALL_APPS
或ALL_APPS_DELTA
。Value
則有一個String
類型的payload和一個byte
數組,表示gzip壓縮後的字節。code
generatePayload()
中根據EntityType
和EntityName
,會調用不一樣的方法獲取regitry中的信息。cdn
registry.getApplications()
: 獲得全部的應用註冊信息,結果爲Applications
對象。registry.getApplicationsDeltas()
:獲得增量更新信息。registry.getApplication()
:獲得單個應用信息。getApplicationsForVip
:就是先獲得全部的應用註冊信息,而後提取出vipAddress
符合請求的應用信息。vip和svip是什麼server
在Spring Cloud Eureka中,這兩個設置變成了VirtualHostName和SecureVirtualHostName,應該是相似DNS名稱。對象
傳入的爲某個應用名,而實際上要讓如下緩存失效:blog
行爲很簡單,就是把readWriteMap拷貝到readOnlyMap(但只拷貝readOnlyCache中已有的key)。 任務執行頻率由eureka.server.responseCacheUpdateIntervalMs
控制,默認爲30秒。
另外,eureka.server.useReadOnlyResponseCache
能夠設置是否啓用readOnlyCache,默認啓用。
前文已述,generatePayload()
方法根據entityName
是ALL_APPS
或ALL_APPS_DELTA
決定生成已註冊的全量信息,仍是增量信息。
調用registry.getApplications()
,最終就是從本地(也可能包含遠程)的registry中讀取全部註冊信息,構形成Applications
對象。
在前兩篇文章中,提到了registry的實現類有一個AbstractInstanceRegistry.recentlyChangedQueue
隊列,保存最近的租約變動記錄。在註冊、下線等操做時,會修改此隊列。
另外,還有一個定時任務專門對超過必定時長的記錄進行移除。定時任務的執行間隔由eureka.server.deltaRetentionTimerIntervalInMs
控制;時長閾值由eureka.server.retentionTimeInMSInDeltaQueue
控制。
客戶端獲取增量信息,與本地緩存合併後通服務端的全量信息比較哈希值(哈希算法有特別實現,主要根據註冊應用內容)。若是哈希值不一樣,則增量獲取失敗,須要一次全量獲取。