天天看點

Spring Cloud Eureka Client 源碼解析(一)預備知識、自動配置類的加載解析1.預備知識2. Eureka Client 自動配置類的加載

1.預備知識

1.1 Region 與 Zone

1.1.1 概念

Spring Cloud Eureka Client 源碼解析(一)預備知識、自動配置類的加載解析1.預備知識2. Eureka Client 自動配置類的加載

Eureka 中具有 Region 與 Availability Zone(簡稱 AZ)概念,是雲計算中的概念。

為了友善不同地理區域中使用者的使用

,大型雲服務提供商一般會根據使用者需求量在不同的城市、省份、國家或洲建立不同的大型雲計算機房。這些不同區域機房間一般是不能“内網連通”的。這些區域就稱為一個 Region。

這裡存在一個問題:同一 Region 機房是如何實作

同域容災

的?為了增強容災能力,在一個 Region 中又設定了不同的

Availability Zone

。這些 AZ 間實作了

内網連通

,且使用者可以根據自己所在的具體位置自動選擇同域中的不同 AZ。當使用者所要通路的 AZ 出現問題後,系統會自動切換到其它可用的 AZ。

例如,AWS 将全球劃分為了很多的 Region,例如美國東部區、美國西部區、歐洲區、非洲開普敦區、亞太區等。像 Eureka 系統架構圖中的 us-east-1c、us-east-1d、us-east-1e 就是 us-east-1 這個 Region 中的 c、d、e 三個 AZ。

再如,阿裡雲在我國境内的 Region 有杭州、北京、深圳、青島、香港等,境外 Region有亞太東南 1 區(新加坡)、亞太東南 2 區(悉尼)、亞太東北 1 區(東京)。

1.1.2 Eureka 中的 Region 與 Zone 配置

(1) 需求

Spring Cloud Eureka Client 源碼解析(一)預備知識、自動配置類的加載解析1.預備知識2. Eureka Client 自動配置類的加載

假設某公司的伺服器有 Beijing、Shanghai 等多個 Region。Beijing 這個 Region 中存在兩個 AZ,分别是 bj-1 與 bj-2,每個 AZ 中有三台 Eureka Server。

h-1 與 h-2 兩台主機提供的都是相同的 Servivce 服務,根據地理位置的不同,這兩台主機分别注冊到了距離自己最近的不同 AZ 的 Eureka Server。

但是因為Region中的AZ都是内網聯通的,是以 整個Region中的每個Eureka Server資料都是一緻的。

(2) 主機配置

Eureka配置:

  • A、Server AZ bj-1

    說明:bj-1 這個 Eureka Server 的 AZ 叢集中具有三台 Server,這三台 Server 的配置檔案,除了 server.port 不同外,其它配置完全相同。

    這三個 Server 的 IP 與端口分别為:ip00:8000,ip01:8001,ip02:8002,該三台主機屬于同一個zone。

    同時需要注意,defaultZone需要配置整個Region中所有的Eureka Server的位址

    配置如下,隻展示了一個,另外兩個隻是端口不同,可以看到是通過中繼資料配置zone的:

    Spring Cloud Eureka Client 源碼解析(一)預備知識、自動配置類的加載解析1.預備知識2. Eureka Client 自動配置類的加載
  • B、 Server AZ bj-2

    說明:bj-2 這個 AZ 叢集中具有三台 Server,這三台 Server 的配置檔案,除了 server.port不同外,其它配置完全相同。

    這三個 Server 的 IP 與端口分别為:ip10:8000,ip11:8001,ip12:8002,該三台主機屬于同一個zone。

    同時需要注意,defaultZone需要配置整個Region中所有的Eureka Server的位址

    配置如下,也是隻展示了一個,另外兩個隻是端口不同:

    Spring Cloud Eureka Client 源碼解析(一)預備知識、自動配置類的加載解析1.預備知識2. Eureka Client 自動配置類的加載

Zuul配置:

  • C、 Zuul AZ bj-1
    Spring Cloud Eureka Client 源碼解析(一)預備知識、自動配置類的加載解析1.預備知識2. Eureka Client 自動配置類的加載
  • D、Zuul AZ bj-2
    Spring Cloud Eureka Client 源碼解析(一)預備知識、自動配置類的加載解析1.預備知識2. Eureka Client 自動配置類的加載

Service配置:

這兩個微服務名稱是相同的,隻是在不同的zone

  • E、 Service AZ bj-1
    Spring Cloud Eureka Client 源碼解析(一)預備知識、自動配置類的加載解析1.預備知識2. Eureka Client 自動配置類的加載
  • F、 Service AZ bj-2
    Spring Cloud Eureka Client 源碼解析(一)預備知識、自動配置類的加載解析1.預備知識2. Eureka Client 自動配置類的加載
可以通過以下配置,讓Eureka Client優先選擇相同zone的應用
Spring Cloud Eureka Client 源碼解析(一)預備知識、自動配置類的加載解析1.預備知識2. Eureka Client 自動配置類的加載
如果目前region中的應用都不能用,可以用以下參數指定其他region
Spring Cloud Eureka Client 源碼解析(一)預備知識、自動配置類的加載解析1.預備知識2. Eureka Client 自動配置類的加載

1.2 核心類

(1) InstanceInfo

簡單來說,該類代表的就是系統資料庫中的一個主機執行個體資訊。每一個注冊到Eureka Server的主機對應一個該類的執行個體。

Spring Cloud Eureka Client 源碼解析(一)預備知識、自動配置類的加載解析1.預備知識2. Eureka Client 自動配置類的加載

兩個時間戳:

後面分析源碼會多次看到兩個時間戳,先簡單介紹一下:

Spring Cloud Eureka Client 源碼解析(一)預備知識、自動配置類的加載解析1.預備知識2. Eureka Client 自動配置類的加載
  • lastDirtyTimestamp:記錄 instanceInfo 在

    Client 端

    被修改的時間。

    這個字段隻會在client端被更新

    , instanceInfo 中任何資訊被修改(資料中心資訊、續約配置資訊、狀态等),都會更新該時間戳。
  • lastUpdatedTimestamp:記錄 instanceInfo 在

    Server 端

    被修改的時間。

    這個字段隻會在server端被更新

    ,server端通常隻會修改 instanceInfo 的狀态資訊(我暫時隻發現隻修改了狀态資訊)。

兩個狀态:

instanceInfo中一共有兩個狀态overriddenStatus和status。

關于overriddenStatus,字面意思是覆寫狀态,它是一個“外部”狀态,可以由外部任何程式進行修改,例如之前示範服務平滑上下線,通過actuator修改伺服器(主機執行個體)狀态,修改的值其實就是overriddenStatus。而overriddenStatus并不代表伺服器真正狀态。

而status是真正的伺服器狀态,但是status的值是通過一套規則計算出來的,其中就需要overriddenStatus,後面分析源碼會看到。

三個修改狀态的方法:

  • setOverriddenStatus

    該方法僅會在 Eureka Server 端被調用。(通過actuator修改狀态UP/DOWN…由用戶端發起請求,服務端處理請求的時候調用)

    Spring Cloud Eureka Client 源碼解析(一)預備知識、自動配置類的加載解析1.預備知識2. Eureka Client 自動配置類的加載
  • setStatusWithoutDirty

    該方法僅會在 Eureka Server 端被調用,在修改 status 時不記錄修改時間戳。

    Spring Cloud Eureka Client 源碼解析(一)預備知識、自動配置類的加載解析1.預備知識2. Eureka Client 自動配置類的加載
  • setStatus

    該方法在 Eureka Client 端調用(定時檢測配置更新的時候),用于設定 instance 的服務狀态。

    Spring Cloud Eureka Client 源碼解析(一)預備知識、自動配置類的加載解析1.預備知識2. Eureka Client 自動配置類的加載
    //InstanceInfo.java
    /**
     * Set the status for this instance.
     *
     * @param status status for this instance.
     * @return the prev status if a different status from the current was set, null otherwise
     */
    public synchronized InstanceStatus setStatus(InstanceStatus status) {
        if (this.status != status) {
            InstanceStatus prev = this.status;//記錄之前狀态
            this.status = status;//更新新的狀态
            setIsDirty();//設定dirty标志,髒資料标記,表示用戶端和服務端之間資料不一緻,需要同步
            return prev;//傳回之前的狀态
        }
        return null;
    }
    /**
     * Sets the dirty flag so that the instance information can be carried to
     * the discovery server on the next heartbeat.
     * 設定dirty标志,以便可以将執行個體資訊傳輸到下一個heartbeat上的發現伺服器。
     * 
     * 簡單來說就是變成髒資料以後,用戶端會發起請求和服務端進行資料同步,後面源碼分析會看到
     */
    public synchronized void setIsDirty() {
        isInstanceInfoDirty = true;
        lastDirtyTimestamp = System.currentTimeMillis();
    }
               

看下都有哪些狀态:

Spring Cloud Eureka Client 源碼解析(一)預備知識、自動配置類的加載解析1.預備知識2. Eureka Client 自動配置類的加載
  • UP:對外提供服務的 啟動狀态,

    Ribbon負載均衡的時候,隻有當 status 的狀态為 UP 時,才能被服務發現,進行服務調用

  • OUT_OF_SERVICE:和DOWN效果一樣,但一般是我們手動通過actuator修改狀态,讓其不提供服務,當然手動修改為DOWN也可以
  • DOWN:一般不是手動修改,而是client和server心跳發生異常的時候,系統自動修改為DOWN
  • STARTING:client啟動過程、初始化過程中的狀态,啟動完成後狀态就變了,一般維持的時間不會很長
  • UNKNOWN:一般來說就是overriddenStatus的初始值
    Spring Cloud Eureka Client 源碼解析(一)預備知識、自動配置類的加載解析1.預備知識2. Eureka Client 自動配置類的加載

InstanceInfo重寫了 equals()方法:

InstanceInfo重寫了 equals()方法,将來兩個InstanceInfo比較,主要看InstanceInfo的id:

Spring Cloud Eureka Client 源碼解析(一)預備知識、自動配置類的加載解析1.預備知識2. Eureka Client 自動配置類的加載

(2) Application

也是系統資料庫中的一部分,簡單來說,系統資料庫中同一個微服務的所有提供者的執行個體InstanceInfo資訊都會維護在該類中,即一種微服務對應一個Application執行個體。

Spring Cloud Eureka Client 源碼解析(一)預備知識、自動配置類的加載解析1.預備知識2. Eureka Client 自動配置類的加載

(3) Applications

這個就是我們說的系統資料庫,維護的是整個從服務端擷取的系統資料庫資訊。

Spring Cloud Eureka Client 源碼解析(一)預備知識、自動配置類的加載解析1.預備知識2. Eureka Client 自動配置類的加載

說明一點:這個類專門為用戶端使用的,實際上服務端的系統資料庫資料結構,就是一個雙層map,後面源碼分析會看到。

(4) Jersey 架構

Eureka Client 與 Eureka Server 間的通信,及各個 Eureka Server 間的通信,使用的是 Jersey 架構完成的(

都是通過http協定進行通信的

)。

Jersey 架構是一個開源的 RESTful 架構。其功能與 SpringMVC 的相同。不同的是 SpringMVC 的處理器是 Controller,而 Jersey 的是 Resource。

2. Eureka Client 自動配置類的加載

PS:對Spring boot自動配置不熟的朋友,可以先去看一下關于SpringBoot自動配置的文章。我的部落格裡也有。

這裡我們主要關注Eureka Client自動配置的時候都加載了哪些東西

入口從Eureka Client依賴開始:

Spring Cloud Eureka Client 源碼解析(一)預備知識、自動配置類的加載解析1.預備知識2. Eureka Client 自動配置類的加載

找到對應的依賴的具體代碼:

Spring Cloud Eureka Client 源碼解析(一)預備知識、自動配置類的加載解析1.預備知識2. Eureka Client 自動配置類的加載
Spring Cloud Eureka Client 源碼解析(一)預備知識、自動配置類的加載解析1.預備知識2. Eureka Client 自動配置類的加載
Spring Cloud Eureka Client 源碼解析(一)預備知識、自動配置類的加載解析1.預備知識2. Eureka Client 自動配置類的加載

Eureka Client相關配置類的加載

關于@EnableConfigurationProperties注解:

Spring Cloud Eureka Client 源碼解析(一)預備知識、自動配置類的加載解析1.預備知識2. Eureka Client 自動配置類的加載

可以看到對于@ConfigurationProperties的類的處理,可以直接在注解的value屬性指定相應類名進行注冊,或者通過 @Bean方法注冊。EurekaClientAutoConfiguration是通過@Bean的方式:

  • EurekaClientConfig
    Spring Cloud Eureka Client 源碼解析(一)預備知識、自動配置類的加載解析1.預備知識2. Eureka Client 自動配置類的加載
    Spring Cloud Eureka Client 源碼解析(一)預備知識、自動配置類的加載解析1.預備知識2. Eureka Client 自動配置類的加載
  • EurekaInstanceConfig
    Spring Cloud Eureka Client 源碼解析(一)預備知識、自動配置類的加載解析1.預備知識2. Eureka Client 自動配置類的加載
    Spring Cloud Eureka Client 源碼解析(一)預備知識、自動配置類的加載解析1.預備知識2. Eureka Client 自動配置類的加載

Eureka Client 的建立

我們現在看我們最核心的EurekaClient的建立

Spring Cloud Eureka Client 源碼解析(一)預備知識、自動配置類的加載解析1.預備知識2. Eureka Client 自動配置類的加載

問題1:

看下@ConditionalOnMissingBean注解的search屬性:

Spring Cloud Eureka Client 源碼解析(一)預備知識、自動配置類的加載解析1.預備知識2. Eureka Client 自動配置類的加載

對應有三種政策:

Spring Cloud Eureka Client 源碼解析(一)預備知識、自動配置類的加載解析1.預備知識2. Eureka Client 自動配置類的加載
Spring Cloud Eureka Client 源碼解析(一)預備知識、自動配置類的加載解析1.預備知識2. Eureka Client 自動配置類的加載

PS:當然判斷的條件和Bean加載的順序也有關,這個其實是SpringBoot自動配置的知識點,不是本篇重點。

問題2:

Spring Cloud Eureka Client 源碼解析(一)預備知識、自動配置類的加載解析1.預備知識2. Eureka Client 自動配置類的加載

在講Spring Cloud Config自動更新配置的時候,其實用過這個注解,這個注解可以讓Spring容器重新整理的時候,讓目前執行個體重新生成新的執行個體。

問題3:

Spring Cloud Eureka Client 源碼解析(一)預備知識、自動配置類的加載解析1.預備知識2. Eureka Client 自動配置類的加載
Spring Cloud Eureka Client 源碼解析(一)預備知識、自動配置類的加載解析1.預備知識2. Eureka Client 自動配置類的加載

懶加載,簡單來說就是如果不從Spring容器中擷取這個bean執行個體,或者被其他執行個體引用,就不會對該bean進行初始化。

即隻有用到的時候才會初始化。

問題4:

Spring Cloud Eureka Client 源碼解析(一)預備知識、自動配置類的加載解析1.預備知識2. Eureka Client 自動配置類的加載

看一下@ConditionalOnMissingRefreshScope注解:

Spring Cloud Eureka Client 源碼解析(一)預備知識、自動配置類的加載解析1.預備知識2. Eureka Client 自動配置類的加載
  • Conditional注解:
    Spring Cloud Eureka Client 源碼解析(一)預備知識、自動配置類的加載解析1.預備知識2. Eureka Client 自動配置類的加載
    Spring Cloud Eureka Client 源碼解析(一)預備知識、自動配置類的加載解析1.預備知識2. Eureka Client 自動配置類的加載
  • 看下具體的條件,OnMissingRefreshScopeCondition類:
    Spring Cloud Eureka Client 源碼解析(一)預備知識、自動配置類的加載解析1.預備知識2. Eureka Client 自動配置類的加載
    Spring Cloud Eureka Client 源碼解析(一)預備知識、自動配置類的加載解析1.預備知識2. Eureka Client 自動配置類的加載

回過頭看@ConditionalOnRefreshScope注解對比以下,看到條件剛好是相反的:

Spring Cloud Eureka Client 源碼解析(一)預備知識、自動配置類的加載解析1.預備知識2. Eureka Client 自動配置類的加載

是以這兩個内置配置類不會同時起作用:

Spring Cloud Eureka Client 源碼解析(一)預備知識、自動配置類的加載解析1.預備知識2. Eureka Client 自動配置類的加載
Spring Cloud Eureka Client 源碼解析(一)預備知識、自動配置類的加載解析1.預備知識2. Eureka Client 自動配置類的加載

繼續閱讀