天天看點

超詳細的Eureka源碼解析

Eureka是什麼?

Eureka是基于REST(Representational State Transfer)服務,主要以AWS雲服務為支撐,提供服務發現并實作負載均衡和故障轉移。我們稱此服務為Eureka服務。Eureka提供了Java用戶端元件,Eureka Client,友善與服務端的互動。用戶端内置了基于round-robin實作的簡單負載均衡。在Netflix,為Eureka提供更為複雜的負載均衡方案進行封裝,以實作高可用,它包括基于流量、資源使用率以及請求傳回狀态的權重負載均衡。

Eureka架構

超詳細的Eureka源碼解析

Eureka架構從CAP理論看,Eureka是一個AP系統,優先保證可用性(A)和分區容錯性(P),Eureka裡使用了大量的緩存。

Eureka中的一些概念

Register :服務注冊

Eureka用戶端向Eureka Server注冊時,它提供自身的中繼資料,比如IP位址、端口等

Renew:服務續約

Eureka用戶端會每隔30秒發送一次心跳來續約。通過續約來告知Eureka Server該用戶端仍然存在。

Fetch Registries:擷取注冊清單資訊

Eureka用戶端從伺服器擷取系統資料庫資訊,将其緩存到本地。用戶端會使用該資訊查找其他服務,進而進行遠端調用。該注冊清單資訊定期(每30秒)更新一次。

Cancel:服務下線

Eureka用戶端在程式關閉時向Eureka伺服器發送取消請求。

Eviction:服務剔除

在預設情況下,當Eureka用戶端90秒沒有向Eureka伺服器發送續約,Eureka伺服器就會将該服務執行個體從服務注冊清單删除。

除了以上的特性外,Eureka的緩存機制也非常經典,下面詳細介紹一下。

Eureka Server裡存在三個變量(registry、readWriteCacheMap、readOnlyCacheMap)儲存服務注冊資訊。

超詳細的Eureka源碼解析

Eureka用戶端向服務端注冊之後,資料會立即同步到readWriteCacheMap和registry。

Eureka用戶端想檢視注冊資訊,每隔30秒從readOnlyCacheMap拉取。

readOnlyCacheMap會通過定時器每30秒從readWriteCacheMap拉取。

還有一個線程每隔60會将90秒都沒有續約的服務剔除出去。

變量

類型

說明

registry

ConcurrentHashMap

實時更新,類AbstractInstanceRegistry成員變量,UI端請求的是這裡的服務注冊資訊

readWriteCacheMap

Guava Cache

實時更新,類ResponseCacheImpl成員變量,緩存時間180秒

readOnlyCacheMap

周期更新,類ResponseCacheImpl成員變量,預設每30s從readWriteCacheMap更新,Eureka client預設從這裡更新服務注冊資訊,可配置直接從readWriteCacheMap更新

本文使用的是2.0.2.RELEASE版本

接下來開始分析Eureka Client的源碼。引入spring-cloud-starter-netflix-eureka-client後,Eureka Client會自動啟用。EurekaClientAutoConfiguration配置類生效,會注入Bean CloudEurekaClient,然後調用父類DiscoveryClient的構造方法。

接下來看initScheduledTasks方法

再來細看上面3個主要方法的具體邏輯。

1. 緩存重新整理

然後調用EurekaHttpClient接口的方法去擷取服務清單。請求發送通過jersey

2. 服務心跳

繼續跟蹤HeartbeatThread方法

3. 服務注冊

跟蹤instanceInfoReplicator.start方法

4. 服務關閉

服務關閉之後,會回調到EurekaAutoServiceRegistration類的stop方法,回調的方法是:

SmartLifecycle接口也有這個作用,不過我本地使用了一下,是通過ContextClosedEvent來回調的。

從上文分析得知Eureka Client調取服務端的接口都是通過EurekaHttpClient接口,而最終發送請求的httpClient是jersey裡面的ApacheHttpClient4。

Eureka Server需要做的事有:

維護服務注冊資訊清單

接收用戶端的register、renew、cancel等請求

Eureka Server多節點之間的資料複制同步

項目啟動時,EurekaServerAutoConfiguration會被自動注入到容器中。

1. 請求接受處理

InstanceResource類主要用于接受請求,收到請求後調用InstanceRegistry類的方法進行處理。以renew為例:

2. 服務剔除

EurekaServerAutoConfiguration類引入了EurekaServerInitializerConfiguration類。容器初始化會觸發start方法,start方法如下:

postInit代碼如下:

3. readOnlyCacheMap緩存周期更新

DefaultEurekaServerContext類的initialize方法上加了@PostConstruct注解,會在bean構造後被執行:

init()-》 initializedResponseCache()-》new ResponseCacheImpl

ResponseCacheImpl方法如下:

番外:源碼裡有一個這個東西,存最近的資料,如果有相同需求可以借鑒

書山有路勤為徑,學海無涯苦作舟