1. 程式人生 > >Spring Cloud分散式微服務雲架構原始碼分析 — Eureka

Spring Cloud分散式微服務雲架構原始碼分析 — Eureka

在看具體原始碼前,我們先回顧一下之前我們所實現的內容,從而找一個合適的切入口去分析。首先,服務註冊中心、服務提供者、服務消費者這三個主要元素來說,後兩者(也就是Eureka客戶端)在整個執行機制中是大部分通訊行為的主動發起者,而註冊中心主要是處理請求的接收者。所以,我們可以從Eureka的客戶端作為入口看看它是如何完成這些主動通訊行為的。

我們在將一個普通的Spring Boot應用註冊到Eureka Server中,或是從Eureka Server中獲取服務列表時,主要就做了兩件事:

  • 在應用主類中配置了@EnableDiscoveryClient註解
  • application.properties
    中用eureka.client.serviceUrl.defaultZone引數指定了服務註冊中心的位置

順著上面的線索,我們先檢視@EnableDiscoveryClient的原始碼如下:

/**
* Annotation to enable a DiscoveryClient implementation.
* @author Spencer Gibb
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(EnableDiscoveryClientImportSelector.class)

public @interface EnableDiscoveryClient {

}

從該註解的註釋我們可以知道:該註解用來開啟DiscoveryClient的例項。通過搜尋DiscoveryClient,我們可以發現有一個類和一個介面。通過梳理可以得到如下圖的關係:

其中,左邊的org.springframework.cloud.client.discovery.DiscoveryClient是Spring Cloud的介面,它定義了用來發現服務的常用抽象方法,而org.springframework.cloud.netflix.eureka.EurekaDiscoveryClient

是對該介面的實現,從命名來就可以判斷,它實現的是對Eureka發現服務的封裝。所以EurekaDiscoveryClient依賴了Eureka的com.netflix.discovery.EurekaClient介面,EurekaClient繼承了LookupService介面,他們都是Netflix開源包中的內容,它主要定義了針對Eureka的發現服務的抽象方法,而真正實現發現服務的則是Netflix包中的com.netflix.discovery.DiscoveryClient類。

那麼,我們就看看來詳細看看DiscoveryClient類。先解讀一下該類頭部的註釋有個總體的瞭解,註釋的大致內容如下:

這個類用於幫助與Eureka Server互相協作。

Eureka Client負責了下面的任務:
- 向Eureka Server註冊服務例項
- 向Eureka Server為租約續期
- 當服務關閉期間,向Eureka Server取消租約
- 查詢Eureka Server中的服務例項列表

Eureka Client還需要配置一個Eureka Server的URL列表。

在具體研究Eureka Client具體負責的任務之前,我們先看看對Eureka Server的URL列表配置在哪裡。根據我們配置的屬性名:eureka.client.serviceUrl.defaultZone,通過serviceUrl我們找到該屬性相關的載入屬性,但是在SR5版本中它們都被@Deprecated標註了,並在注視中可以看到@link到了替代類com.netflix.discovery.endpoint.EndpointUtils,我們可以在該類中找到下面這個函式:

public static Map<String, List<String>> getServiceUrlsMapFromConfig(
EurekaClientConfig clientConfig, String instanceZone, boolean preferSameZone) {
Map<String, List<String>> orderedUrls = new LinkedHashMap<>();
String region = getRegion(clientConfig);
String[] availZones = clientConfig.getAvailabilityZones(clientConfig.getRegion());
if (availZones == null || availZones.length == 0) {
availZones = new String[1];
availZones[0] = DEFAULT_ZONE;
}
……
int myZoneOffset = getZoneOffset(instanceZone, preferSameZone, availZones);

String zone = availZones[myZoneOffset];
List<String> serviceUrls = clientConfig.getEurekaServerServiceUrls(zone);
if (serviceUrls != null) {
orderedUrls.put(zone, serviceUrls);
}
……
return orderedUrls;
}

Region、Zone

在上面的函式中,我們可以發現客戶端依次載入了兩個內容,第一個是Region,第二個是Zone,從其載入邏上我們可以判斷他們之間的關係:

  • 通過getRegion函式,我們可以看到它從配置中讀取了一個Region返回,所以一個微服務應用只可以屬於一個Region,如果不特別配置,就預設為default。若我們要自己設定,可以通過eureka.client.region屬性來定義。
public static String getRegion(EurekaClientConfig clientConfig) {
String region = clientConfig.getRegion();
if (region == null) {
region = DEFAULT_REGION;
}
region = region.trim().toLowerCase();
return region;
}
  • 通過getAvailabilityZones函式,我們可以知道當我們沒有特別為Region配置Zone的時候,將預設採用defaultZone,這也是我們之前配置引數eureka.client.serviceUrl.defaultZone的由來。若要為應用指定Zone,我們可以通過eureka.client.availability-zones屬性來進行設定。從該函式的return內容,我們可以Zone是可以有多個的,並且通過逗號分隔來配置。由此,我們可以判斷Region與Zone是一對多的關係。
public String[] getAvailabilityZones(String region) {
String value = this.availabilityZones.get(region);
if (value == null) {
value = DEFAULT_ZONE;
}
return value.split(",");
}

ServiceUrls

在獲取了Region和Zone資訊之後,才開始真正載入Eureka Server的具體地址。它根據傳入的引數按一定演算法確定載入位於哪一個Zone配置的serviceUrls。

int myZoneOffset = getZoneOffset(instanceZone, preferSameZone, availZones);
String zone = availZones[myZoneOffset];
List<String> serviceUrls = clientConfig.getEurekaServerServiceUrls(zone);

具體獲取serviceUrls的實現,我們可以詳細檢視getEurekaServerServiceUrls函式的具體實現類EurekaClientConfigBean,該類是EurekaClientConfigEurekaConstants介面的實現,用來載入配置檔案中的內容,這裡有非常多有用的資訊,這裡我們先說一下此處我們關心的,關於defaultZone的資訊。通過搜尋defaultZone,我們可以很容易的找到下面這個函式,它具體實現了,如何解析該引數的過程,通過此內容,我們就可以知道,eureka.client.serviceUrl.defaultZone屬性可以配置多個,並且需要通過逗號分隔。

public List<String> getEurekaServerServiceUrls(String myZone) {
String serviceUrls = this.serviceUrl.get(myZone);
if (serviceUrls == null || serviceUrls.isEmpty()) {
serviceUrls = this.serviceUrl.get(DEFAULT_ZONE);
}
if (!StringUtils.isEmpty(serviceUrls)) {
final String[] serviceUrlsSplit = StringUtils.commaDelimitedListToStringArray(serviceUrls);
List<String> eurekaServiceUrls = new ArrayList<>(serviceUrlsSplit.length);
for (String eurekaServiceUrl : serviceUrlsSplit) {
if (!endsWithSlash(eurekaServiceUrl)) {
eurekaServiceUrl += "/";
}
eurekaServiceUrls.add(eurekaServiceUrl);
}
return eurekaServiceUrls;
}
return new ArrayList<>();
}

當客戶端在服務列表中選擇例項進行訪問時,對於Zone和Region遵循這樣的規則:優先訪問同自己一個Zone中的例項,其次才訪問其他Zone中的例項。通過Region和Zone的兩層級別定義,配合實際部署的物理結構,我們就可以有效的設計出區域性故障的容錯叢集。


從現在開始,我這邊會將近期研發的springcloud微服務雲架構的搭建過程和精髓記錄下來,幫助更多有興趣研發spring cloud框架的朋友,希望可以幫助更多的好學者。大家來一起探討spring cloud架構的搭建過程及如何運用於企業專案。原始碼來源

相關推薦

Spring Cloud分散式微服務架構原始碼分析Eureka

在看具體原始碼前,我們先回顧一下之前我們所實現的內容,從而找一個合適的切入口去分析。首先,服務註冊中心、服務提供者、服務消費者這三個主要元素來說,後兩者(也就是Eureka客戶端)在整個執行機制中是大部分通訊行為的主動發起者,而註冊中心主要是處理請求的接收者。所以,我們可

Java架構-(四)整合spring cloud服務架構 - 企業分散式微服務架構構建

今天正式給大家介紹了Spring Cloud - 企業分散式微服務雲架構構建,我這邊結合了當前大部分企業的通用需求,包括技術的選型比較嚴格、苛刻,不僅要用業界最流行的技術,還要和國際接軌,在未來的5~10年內不能out。作為公司的架構師,也要有一種放眼世界的眼光,不僅要給公司做好的技術選

Spring Cloud--鴻鵠Cloud分散式微服務系統—架構程式碼結構構建

根據微服務化設計思想,結合springcloud一些優秀的專案,如服務發現、治理、配置化管理、路由負載、安全控制等優秀解決方案,使用Maven技術將框架進行模組化、服務化、原子化封裝並構建,也為後期的灰度釋出、持續整合提前做好準備工作。 另外在搭建環境之前,大家需要熟練掌握

Spring Cloud+Spring Boot+Mybatis+shiro +微服務 企業分散式微服務架構技術分享

1.   介紹Commonservice-system是一個大型分散式、微服務、面向企業的JavaEE體系快速研發平臺,基於模組化、服務化、原子化、熱插拔的設計思想,使用成熟領先的無商業限制的主流開源技術構建。採用服務化的元件開發模式,可實現複雜的業務功能。提供驅動式開發模式

spring cloud + spring boot + springmvc+mybatis分散式微服務架構

做一個微服務架構需要的技術整理:View: H5、Vue.js、Spring Tag、React、angularJsSpring Boot/Spring Cloud:Zuul、Ribbon、Feign、Turbine、Hystrix、Oauthor2、Sleuth、API G

Spring Cloud Spring Boot mybatis分散式微服務架構(一)快速入門

快速入門本章主要目標完成Spring Boot基礎專案的構建,並且實現一個簡單的Http請求處理,通過這個例子對Spring Boot有一個初步的瞭解,並體驗其結構簡單、開發快速的特性。系統要求:Java 7及以上Spring Framework 4.1.5及以上本文采用Ja

Spring Cloud-鴻鵠Cloud分散式微服務系統—System系統管理

1.   介紹 Commonservice-system是一個大型分散式、微服務、面向企業的JavaEE體系快速研發平臺,基於模組化、服務化、原子化、熱插拔的設計思想,使用成熟領先的無商業限制的主流開源技術構建。採用服務化的元件開發模式,可實現複雜的業務功能。提供驅動式開發模式

(一)spring cloud網際網路分散式微服務平臺規劃分析--spring cloud平臺整體規

導語 近期公司孵化了一個網際網路產品,隨著業務發展,產品運營後用戶資料量(過億)、業務資料量(過100億)較大,技術團隊配合產品、運營快速定製化開發, 還要考慮產品涉及的資金安全、訊息的及時性、業務的制動化處理,我們選擇鴻鵠cloud分散式雲架構平臺作為公司產品核心企業架構。 產品平臺規

spring cloud網際網路分散式微服務平臺規劃分析--spring cloud平臺整體規劃

1. 導語 近期公司孵化了一個網際網路產品,隨著業務發展,產品運營後用戶資料量(過億)、業務資料量(過100億)較大,技術團隊配合產品、運營快速定製化開發, 還要考慮產品涉及的資金安全、訊息的及時性、業務的制動化處理,我們選擇鴻鵠cloud分散式雲架構平臺作為公司產品核心企業架構。 2.

spring cloud網際網路分散式微服務平臺規劃分析--spring cloud定時排程平臺

1.介紹 鴻鵠雲架構【定時排程平臺】是一個完全由Java編寫的開源任務排程框架,為企業在任務排程提供了簡單卻強大的機制。開發人員根據業務規則,使用排程平臺簡單配置,就可以讓任務在特定時間特定階段進行執行。特點如下: 1.強大的排程功能,例如支援豐富多樣的排程方法,可以滿足各種常規及特殊需求。

spring cloud網際網路分散式微服務平臺規劃分析--spring cloud服務監控中心

1.介紹 鴻鵠雲架構【服務監控中心】提供簡潔的視覺化WEB UI,來管理 Spring Cloud 微服務應用程式。 2.平臺基礎功能 服務線上狀態監控、Logging日誌級別管理、JMX beans管理、Threads會話和執行緒管理、Trace應用請求跟蹤 應用執行引數資訊 更多資源歡迎

spring cloud網際網路分散式微服務平臺規劃分析--spring cloud系統管理平臺

1.介紹 鴻鵠雲架構【系統管理平臺】是一個大型企業、分散式、微服務、雲架構的JavaEE體系快速研發平臺,基於模組化、微服務化、原子化、熱部署的設計思想,使用成熟領先的無商業限制的主流開源技術構建。 採用服務化的元件開發模式,可實現複雜的業務功能。使用Maven進行專案的構建管理,採用Jenkins進行持續

Spring Cloud--Honghu Cloud 分散式微服務系統-Eureka(六)

我們針對於HongHu cloud的eureka專案做以下構建,整個構建的過程很簡單,我會將每一步都構建過程記錄下來,希望可以幫助到大家。 1. 建立一個名為common-eureka的maven專案,繼承commonservice,具體的pom.xml配置檔案如下: &

(一)spring cloud網際網路分散式微服務平臺規劃分析--spring cloud平臺整體規劃

1. 導語 近期公司孵化了一個網際網路產品,隨著業務發展,產品運營後用戶資料量(過億)、業務資料量(過100億)較大,技術團隊配合產品、運營快速定製化開發, 還要考慮產品涉及的資金安全、訊息的及時性、業務的制動化處理,我們選擇鴻鵠cloud分散式雲架構平臺作為公司產品核心

springcloud Spring Boot mybatis分散式微服務架構(六):配置中心

下面針對該Controller編寫測試用例驗證正確性,具體如下。當然也可以通過瀏覽器外掛等進行請求提交驗證。 @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes =

(一)Honghu Cloud 網際網路分散式微服務平臺規劃分析--平臺整體規劃

1. 導語 近期公司孵化了一個網際網路產品,隨著業務發展,產品運營後用戶資料量(過億)、業務資料量(過100億)較大,技術團隊配合產品、運營快速定製化開發, 還要考慮產品涉及的資金安全、訊息的及時性、業務的制動化處理,我們選擇鴻鵠cloud分散式雲架構平臺作為公司產品核心企業架構。 &n

SpringCloud微服務架構構建B2B2C電子商務平臺之-企業分散式微服務架構構建(四)

今天正式給大家介紹了Spring Cloud - 企業分散式微服務雲架構構建,我這邊結合了當前大部分企業的通用需求,包括技術的選型比較嚴格、苛刻,不僅要用業界最流行的技術,還要和國際接軌,在未來的5~10年內不能out。作為公司的架構師,也要有一種放眼世界的眼光,不僅要給公司做好的技術選型,而且還要快速響應企

介紹一個Spring Cloud分散式微服務架構圖

分散式、微服務、雲架構 JAVA語言開發、跨平臺、高效能、高可用、安全、服務化、模組化、元件化、驅動式開發模式 從現在開始,我這邊會將近期研發的springcloud微服務雲架構的搭建過程和精髓記錄下來,幫助更多有興趣研發spring cloud框架的朋友,希望可

分散式微服務架構dubbo+zookeeper+springmvc+mybatis+shiro+redis例項

原始碼結構 JEESZ驅動式專案構建 內建高效可靠的程式碼生成器 支援多種資料模型,根據資料庫表生成常規重複性程式碼,使研發工程師更專注於業務邏輯程式碼的實現,大幅提升其工作效率,解放其重複性工作 OPEN CI 開源規範化專案管理解決方案,實現軟體流水線式

java版電子商務spring cloud分散式微服務b2b2c社交電商 (十四)服務註冊(consul)

Springcloud b2b2c電子商務社交平臺原始碼請加企鵝求求:一零三八七七四六二六。這篇文章主要介紹 spring clo