SpringCloud(一)之微服務核心組件Eureka(注冊中心)的介紹和使用


一 Eureka服務治理體系
1.1 服務治理
服務治理是微服務架構中最為核心和基礎的模塊,它主要用來實現各個微服務實例的自動化注冊和發現。

Spring Cloud Eureka是Spring Cloud Netflix微服務套件中的一部分,它基於Netflix Eureka做了二次封裝。主要負責完成微服務架構中的服務治理功能。

 

Eureka服務治理體系如下:


1.2 服務注冊
在服務治理框架中,通常都會構建一個注冊中心,每個服務單元向注冊中心登記自己提供的服務,包括服務的主機與端口號、服務版本號、通訊協議等一些附加信息。注冊中心按照服務名分類組織服務清單,同時還需要以心跳檢測的方式去監測清單中的服務是否可用,若不可用需要從服務清單中剔除,以達到排除故障服務的效果。

1.3 服務發現
在服務治理框架下,服務間的調用不再通過指定具體的實例地址來實現,而是通過服務名發起請求調用實現。服務調用方通過服務名從服務注冊中心的服務清單中獲取服務實例的列表清單,通過指定的負載均衡策略取出一個服務實例位置來進行服務調用。

二 Netflix Eureka
2.1 Netflix Eureka介紹
Spirng Cloud Eureka使用Netflix Eureka來實現服務注冊與發現。它既包含了服務端組件,也包含了客戶端組件,並且服務端與客戶端均采用java編寫,所以Eureka主要適用於通過java實現的分布式系統,或是JVM兼容語言構建的系統。Eureka的服務端提供了較為完善的REST API,所以Eureka也支持將非java語言實現的服務納入到Eureka服務治理體系中來,只需要其他語言平台自己實現Eureka的客戶端程序。目前.Net平台的Steeltoe、Node.js的eureka-js-client等都已經實現了各自平台的Ereka客戶端組件。

2.2 Eureka服務端
    Eureka服務端,即服務注冊中心。它同其他服務注冊中心一樣,支持高可用配置。依托於強一致性提供良好的服務實例可用性,可以應對多種不同的故障場景。

   Eureka服務端支持集群模式部署,當集群中有分片發生故障的時候,Eureka會自動轉入自我保護模式。它允許在分片發生故障的時候繼續提供服務的發現和注冊,當故障分配恢復時,集群中的其他分片會把他們的狀態再次同步回來。集群中的的不同服務注冊中心通過異步模式互相復制各自的狀態,這也意味着在給定的時間點每個實例關於所有服務的狀態可能存在不一致的現象。

2.3 Eureka客戶端
Eureka客戶端,主要處理服務的注冊和發現。客戶端服務通過注冊和參數配置的方式,嵌入在客戶端應用程序的代碼中。在應用程序啟動時,Eureka客戶端向服務注冊中心注冊自身提供的服務,並周期性的發送心跳來更新它的服務租約。同時,他也能從服務端查詢當前注冊的服務信息並把它們緩存到本地並周期行的刷新服務狀態。

三 服務注冊中心
3.1 服務注冊中心功能概述
在服務治理框架中,通常都會構建一個注冊中心,每個服務單元向注冊中心登記自己提供的服務,包括服務的主機與端口號、服務版本號、通訊協議等一些附加信息。注冊中心按照服務名分類組織服務清單,同時還需要以心跳檢測的方式去監測清單中的服務是否可用,若不可用需要從服務清單中剔除,以達到排除故障服務的效果。

 

3.2 創建Eureka Server服務

  3.2.1 可以通過Idea 創建項目時直接勾選

 3.2.2 可以導入依賴

<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

3.3 Eureka Server相關配置

官方文檔:http://cloud.spring.io/spring-cloud-netflix/single/spring-cloud-netflix.html#spring-cloud-eureka-server

 



#服務注冊中心端口號
server:
port: 8761
#服務注冊中心實例的主機名
eureka:
instance:
hostname: localhost
client:
#是否向服務注冊中心注冊自己
registerWithEureka: false
#是否檢索服務
fetchRegistry: false
serviceUrl:
#服務注冊中心的配置內容,指定服務注冊中心的位置
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

 

3.4 啟動服務注冊中心

@SpringBootApplication
//啟動Eureka服務注冊中心
@EnableEurekaServer
public class EurekaServerApplication {

public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}

3.5 Eureka可視化界面

3.5 高可用服務注冊中心
3.5.1 高可用服務注冊中心的概念
考慮到發生故障的情況,服務注冊中心發生故障必將會造成整個系統的癱瘓,因此需要保證服務注冊中心的高可用。

Eureka Server在設計的時候就考慮了高可用設計,在Eureka服務治理設計中,所有節點既是服務的提供方,也是服務的消費方,服務注冊中心也不例外。

Eureka Server的高可用實際上就是將自己做為服務向其他服務注冊中心注冊自己,這樣就可以形成一組互相注冊的服務注冊中心,以實現服務清單的互相同步,達到高可用的效果。

3.5.2 構建服務注冊中心集群
Eureka Server的同步遵循着一個非常簡單的原則:只要有一條邊將節點連接,就可以進行信息傳播與同步。可以采用兩兩注冊的方式實現集群中節點完全對等的效果,實現最高可用性集群,任何一台注冊中心故障都不會影響服務的注冊與發現

(1)創建application-peer1.properties

     server.port=1111

eureka.instance.hostname=master

eureka.client.register-with-eureka=false

eureka.client.fetch-registry=false

eureka.instance.preferIpAddress=true

eureka.server.enableSelfPreservation=false

eureka.client.serviceUrl.defaultZone=http://backup1:1112/eureka/,http://backup2:1113/eureka/

(2)創建application-peer2.properties

server.port=1112

eureka.instance.hostname=backup1

eureka.client.register-with-eureka=false

eureka.client.fetch-registry=false

eureka.instance.preferIpAddress=true

eureka.server.enableSelfPreservation=false

eureka.client.serviceUrl.defaultZone=http://master:1111/eureka/,http://backup2:1113/eureka/

(3)創建application-peer3.properties

server.port=1113

eureka.instance.hostname=backup2

eureka.client.register-with-eureka=false

eureka.client.fetch-registry=false

eureka.instance.preferIpAddress=true

eureka.server.enableSelfPreservation=false

eureka.client.serviceUrl.defaultZone=http://master:1111/eureka/,http://backup1:1112/eureka/

(4) 在hosts文件中增加如下配置

127.0.0.1 master

127.0.0.1 backup1

127.0.0.1 backup2

3.6 失效剔除
有些時候,我們的服務實例並不一定會正常下線,可能由於內存溢出、網絡故障等原因使服務不能正常運作。而服務注冊中心並未收到“服務下線”的請求,為了從服務列表中將這些無法提供服務的實例剔除,Eureka Server在啟動的時候會創建一個定時任務,默認每隔一段時間(默認為60秒)將當前清單中超時(默認為90秒)沒有續約的服務剔除出去。

3.7 自我保護
服務注冊到Eureka Server后,會維護一個心跳連接,告訴Eureka Server自己還活着。Eureka Server在運行期間會統計心跳失敗的比例在15分鍾以之內是否低於85%,如果出現低於的情況,Eureka Server會將當前實例注冊信息保護起來,讓這些實例不會過期。這樣做會使客戶端很容易拿到實際已經不存在的服務實例,會出現調用失敗的情況。因此客戶端要有容錯機制,比如請求重試、斷路器。

以下是自我保護相關的屬性:

eureka.server.enableSelfPreservation=true. 可以設置改參數值為false,以確保注冊中心將不可用的實例刪除

 

3.8 region(地域)與zone(可用區)
region和zone(或者Availability Zone)均是AWS的概念。在非AWS環境下,我們可以簡單地將region理解為地域,zone理解成機房。一個region可以包含多個zone,可以理解為一個地域內的多個不同的機房。不同地域的距離很遠,一個地域的不同zone間距離往往較近,也可能在同一個機房內。

region可以通過配置文件進行配置,如果不配置,會默認使用us-east-1。同樣Zone也可以配置,如果不配置,會默認使用defaultZone。

Eureka Server通過eureka.client.serviceUrl.defaultZone屬性設置Eureka的服務注冊中心的位置。

指定region和zone的屬性如下:

(1)eureka.client.availabilityZones.myregion=myzone# myregion是region

(2)eureka.client.region=myregion

     Ribbon的默認策略會優先訪問通客戶端處於同一個region中的服務端實例,只有當同一個zone中沒有可用服務端實例的時候才會訪問其他zone中的實例。所以通過zone屬性的定義,配合實際部署的物理結構,我們就可以設計出應對區域性故障的容錯集群。

3.9 安全驗證
我們啟動了Eureka Server,然后在瀏覽器中輸入http://localhost:8761/后,直接回車,就進入了spring cloud的服務治理頁面,這么做在生產環境是極不安全的,下面,我們就給Eureka Server加上安全的用戶認證.

(1)pom文件中引入依賴

<dependency> 

   <groupId>org.springframework.boot</groupId> 

   <artifactId>spring-boot-starter-security</artifactId> 

</dependency> 

(2)serviceurl中加入安全校驗信息

eureka.client.serviceUrl.defaultZone=http://<username>:<password>@${eureka.instance.hostname}:${server.port}/eureka/

 

四 服務提供者
4.1 服務注冊
服務提供者在啟動的時候會通過REST請求的方式將自己注冊到Eureka Server上,同時帶上自身服務的一些元數據信息。Eureka Server接收到這個Rest請求之后,將元數據信息存儲在一個雙層結構的Map中,其中第一層的key是服務名。第二層的key 是具體服務的實例名。

在服務注冊時,需要確認一下eureka.client.register-with-eureka=true參數是否正確,該值默認為true。若設置為fasle將不會啟動注冊操作。

4.2 服務同步
從eureka服務治理體系架構圖中可以看到,不同的服務提供者可以注冊在不同的服務注冊中心上,它們的信息被不同的服務注冊中心維護。

此時,由於多個服務注冊中心互相注冊為服務,當服務提供者發送注冊請求到一個服務注冊中心時,它會將該請求轉發給集群中相連的其他注冊中心,從而實現服務注冊中心之間的服務同步。通過服務同步,提供者的服務信息就可以通過集群中的任意一個服務注冊中心獲得。

4.3 服務續約
在注冊服務之后,服務提供者會維護一個心跳用來持續高速Eureka Server,“我還在持續提供服務”,否則Eureka Server的剔除任務會將該服務實例從服務列表中排除出去。我們稱之為服務續約。

下面是服務續約的兩個重要屬性:

(1)eureka.instance.lease-expiration-duration-in-seconds

leaseExpirationDurationInSeconds,表示eureka server至上一次收到client的心跳之后,等待下一次心跳的超時時間,在這個時間內若沒收到下一次心跳,則將移除該instance。

默認為90秒
如果該值太大,則很可能將流量轉發過去的時候,該instance已經不存活了。
如果該值設置太小了,則instance則很可能因為臨時的網絡抖動而被摘除掉。
該值至少應該大於leaseRenewalIntervalInSeconds
(2)eureka.instance.lease-renewal-interval-in-seconds

leaseRenewalIntervalInSeconds,表示eureka client發送心跳給server端的頻率。如果在leaseExpirationDurationInSeconds后,server端沒有收到client的心跳,則將摘除該instance。除此之外,如果該instance實現了HealthCheckCallback,並決定讓自己unavailable的話,則該instance也不會接收到流量。

默認30秒

4.4 創建並注冊服務提供者
4.4.1 創建Eureka客戶端服務
創建一個Spring Boot工程,命名問Eureka-Client,並在pom文件中引入依賴:

    <dependencies>

        <dependency>

            <groupId>org.springframework.cloud</groupId>

            <artifactId>spring-cloud-starter-eureka</artifactId>

        </dependency>  

    </dependencies>

    <dependencyManagement>

        <dependencies>

            <dependency>

                <groupId>org.springframework.cloud</groupId>

                <artifactId>spring-cloud-dependencies</artifactId>

                <version>${spring-cloud.version}</version>

                <type>pom</type>

                <scope>import</scope>

            </dependency>

        </dependencies>

    </dependencyManagement>

4.4.2 Eureka Client相關配置
在Eureka客戶端需要在appilication.properties文件中指定服務注冊中心的地址

server:
port: 8781
eureka:
client:
serviceUrl:
#在此指定服務注冊中心地址
defaultZone: http://localhost:8761/eureka/
#在此指定服務的名字
spring:
application:
name: order-service

五 服務消費者
5.1 獲取服務
消費者服務啟動時,會發送一個Rest請求給服務注冊中心,來獲取上面注冊的服務清單。為了性能考慮,Eureka Server會維護一份只讀的服務注冊清單來返回給客戶端,同時該緩存清單默認會每隔30秒更新一次。

下面是獲取服務的兩個重要的屬性:

(1)      eureka.client.fetch-registry

是否需要去檢索尋找服務,默認是true

(2)eureka.client.registry-fetch-interval-seconds

表示eureka client間隔多久去拉取服務注冊信息,默認為30秒,對於api-gateway,如果要迅速獲取服務注冊狀態,可以縮小該值,比如5秒

5.2 服務調用
服務消費者在獲取服務清單后,通過服務名可以獲取具體提供服務的實例名和該實例的元數據信息。因為有這些服務實例的詳細信息,所以客戶端可以根據自己的需要決定具體調用哪個實例,在Ribbon中會默認采用輪詢的方式進行調用,從而實現客戶端的負載均衡。

5.3 服務下線
在系統運行過程中必然會面臨關閉或重啟服務的某個實例的情況,在服務關閉操作時,會觸發一個服務下線的Rest服務請求給Eureka Server,告訴服務注冊中心:“我要下線了。”服務端在接收到該請求后,將該服務狀態置位下線(DOWN),並把該下線事件傳播出去。

六 配置詳解

 

七 服務實例類配置
7.1 端點配置
eureka實例的狀態頁面和健康監控的url默認為spring boot actuator提供的/info端點和/health端點。我們必須確保Eureka客戶端的/health端點在發送元數據的時候,是一個能夠被注冊中心訪問到的地址,否則服務注冊中心不會根據應用的健康檢查來更改狀態(僅當開啟了healthcheck功能時,以該端點信息作為健康檢查標准)。而如果/info端點不正確的話,會導致在Eureka面板中單擊服務時,無法訪問到服務實例提供的信息接口。

大多數情況下,我們不需要修改這個幾個url配置。但是當應用不使用默認的上下文(context path或servlet path,比如配置server.servletPath=/test),或者管理終端路徑(比如配置management.contextPath=/admin)時,我們需要修改健康檢查和狀態頁的url地址信息。


application.yml配置文件如下:

server.context-path=/helloeureka

//下面配置為相對路徑,也支持配置成絕對路徑,例如需要支持https

eureka.instance.health-check-url-path=${server.context-path}/health

eureka.instance.status-page-url-path=${server.context-path}/info

7.2 元數據
元數據是Eureka客戶端在向服務注冊中心發送注冊請求時,用來描述自身服務信息的對象,其中包含了一些標准化的元數據,比如服務名稱、實例名稱、實例IP、實例端口等用於服務治理的重要信息;以及一些用於負載均衡策略或是其他特殊用途的自定義元數據信息。

我們可以通過eureka.instance.<properties>=<value>的格式對標准化元數據直接進行配置,其中<properties>就是EurekaInstanceConfigBean對象中的成員變量。而對於自定義元數據,可以通過eureka.instance.metadataMap.<key>=<value>的格式來進行配置。比如:

eureka.instance.metadataMap.zone=tianjin

//隨機生成實例名

eureka.instance.metadataMap.instanceId=${spring.application.name}:${random.value}

7.3 健康檢測
默認情況下,Eureka中各個服務實例的健康檢測並不是通過spring-boot-acturator模塊的/health端點來實現的,而是依靠客戶端心跳的方式來保持服務實例的存活。在Eureka的服務續約與剔除機制下,客戶端的健康狀態從注冊到注冊中心開始都會處於UP狀態,除非心跳終止一段時間之后,服務注冊中心將其剔除。默認的心跳實現方式可以有效檢查客戶端進程是否正常運作,但卻無法保證客戶端應用能夠正常提供服務。

在Spring Cloud Eureka中,可以把Eureka客戶端的健康檢測交給spring-boot-actuator模塊的health端點,以實現更加全面的健康狀態維護,設置方式如下:

(1)      在pom.xml中引入spring-boot-starter-actuator模塊的依賴

(2)      在application.properties中增加參數配置eureka.client.healthcheck.enabled=true

7.4 其他配置
      除了上述配置參數外,下面整理了一些EurekaInstanceConfigBean中定義的配置參數以及對應的說明和默認值,這些參數均以eureka.instance為前綴。

八 通訊協議

默認情況下,Eureka使用Jersey和XStream配合JSON作為Server與Client之間的通訊協議。也可以選擇實現自己的協議來代替(https://blog.csdn.net/sunhuiliang85/article/details/76222517)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM