1. 程式人生 > >eureka詳解(spring cloud 微服務實戰的理解)

eureka詳解(spring cloud 微服務實戰的理解)

概述

這篇文章主要講的是eureka的架構和詳細配置。

eureka的架構

eureka的基礎架構可以分成三個部分:
	1.服務註冊中心:提供服務的發現和註冊的功能。
	2.服務提供者:提供服務的應用,可以是spring boot應用,也可以是其他遵循eureka通訊機制的應用。
	3.消費者應用從服務註冊中心獲取服務列表,從而使消費者可以知道去何處呼叫所v需要的服務。既可以使用Ribbon,也可以使用Feign.

如圖所示

在這裡插入圖片描述

註明:這張圖來自於 spring cloud 微服務實戰一書。

服務提供者

服務註冊
“服務提供者”在啟動的時候會通過傳送REST請求的方式將自己註冊到Eureka Server上,同時帶上了自身服務的一些元
資料資訊。Eureka Server接收到這個REST請求之後,將元資料資訊儲存在一個雙層結構Map中。其中第一層的key是服
務名,第二層的key是具體服務的例項名。
服務同步
比如在上圖中所示,這裡的兩個服務提供者分別註冊到了兩個不同的服務註冊中心上。
資訊分別被兩個註冊中心所維護。同時,這兩個服務註冊中心又相互註冊,當服務提供
這傳送註冊請求到一個服務註冊中心的時候,它會將該請求轉發給叢集中相互連線的其他註冊中心,從而實現了服務的同步。
服務續約
在註冊完成服務之後,服務提供者會維護一個心跳用來持續告訴eureka server,我還活著。
以防止eureka server將該服務從服務列表中排除出去,這種操作就叫做服務續約。
eureka.instance.lease-renewal-interval-in-seconds引數用於定義服務續約任務的呼叫
間隔時間,預設為30秒。eureka.instance.lease-expiration-duration-in-
seconds引數用於定義服務失效的時間,預設為90秒。

服務消費者

獲取服務
當我們啟動服務消費者的時候,他會發送一個Rest請求到服務註冊中i效能,來獲取
上面註冊的服務清單。為了效能考慮,eureka server會維護一份只讀的服務清單返回給客
戶端,同時該快取清單會每隔30秒更新一次。若希望修改快取清單的更新時間,可以
通過eureka.client.registry-fetch-interval-seconds=30引數進行修改,該引數預設值為30,
單位為秒。
服務呼叫
服務消費者在獲取服務清單後,通過服務名可以獲得具體提供服務的例項名和該例項
的元資料資訊。因為有這些服務例項的詳細資訊,所以客戶端可以根據自己的需要決
定具體呼叫哪個例項,在Ribbon中會預設採用輪詢的方式進行呼叫,從而實現客戶端的
負載均衡。
服務下線
在系統執行過程中必然會面臨關閉或重啟服務的某個例項的情況,在服務關閉期間,我
們自然不希望客戶端會繼續呼叫關閉了的例項。所以在客戶端程式中,當服務例項進
行正常的關閉操作時,它會觸發一個服務下線的REST請求給Eureka Server,告訴服務注
冊中心: "我要下線了”。服務端在接收到請求之後,將該服務狀態置為下線(DOWN),並
把該下線事件傳播出去。

服務註冊中心

失效剔除
有些時候,我們的服務例項並不一定會正常下線,可能由於記憶體溢位、網路故障等原因
使得服務不能正常工作,而服務註冊中心並未收到“服務下線”的請求。為了從服務列表
中將這些無法提供服務的例項剔除, Eureka Server在啟動的時候會建立一個定時任務,
預設每隔一段時間(預設為60秒)將當前清單中超時(預設為90秒)沒有續約的服務剔除
出去。
自我保護
有的時候會遇到這樣的:EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING 
INSTANCES ARE UP WHEN  THEY'RE NOT.RENEWALS ARE LESSER THAN THRE
SHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPIRED JUSTTO BE SAFE.
實際上,該警告就是觸發了Eureka Server的自我保護機制。之前我們介紹過,服務註冊到
Eureka Server之後,會維護一個心跳連線,告訴Eureka Server自己還活著。Eureka Server
在執行期間,會統計心跳失敗的比例在15分鐘之內是否低於85%,如果出現低於的情況(在
單機除錯的時候很容易滿足,實際在生產環境上通常是由於網路不穩定導致), EurekaSer
ver會將當前的例項註冊資訊保護起來,讓這些例項不會過期,儘可能保護這些註冊資訊。
但是,在這段保護期間內例項若出現問題,那麼客戶端很容易拿到實際已經不存在的服務
例項,會出現呼叫失敗的情況,所以客戶端必須要有容錯機制,比如可以使用請求重試、
斷路器等機制。
由於本地除錯很容易觸發註冊中心的保護機制,這會使得註冊中心維護的服務例項不那麼
準確。所以,我們在本地進行開發的時候,可以使用eureka.server.enable-self-preservation
=false引數來關閉保護機制,以確保註冊中心可以將不可用的實,例正確剔除。

詳細配置

Eureka客戶端的配置主要分為以下兩個方面。
	·服務註冊相關的配置資訊,包括服務註冊中心的地址、服務獲取的間隔時間、可用區域等。
	·服務例項相關的配置資訊,包括服務例項的名稱、IP地址、埠號、健康檢查路徑等。

服務註冊類配置

指定註冊中心
在配置檔案中指定註冊中心,主要通過eureka.client.serviceUrl引數實現。該引數的定義如下所示,它的配置值儲存在
HashMap型別中,並且設定有一組預設值,預設值的key為defaultZone、 value為http://localhost:8761/eureka/。、
另外,為了服務註冊中心的安全考慮,很多時候我們都會為服務註冊中心加入安全校驗。這個時候,在配置  serviceUrl時,
需要在value值的URL中加入相應的安全校驗資訊,比如http: //<username>: <password>@localhost: 1111/eureka.其中,
<username>為安全校驗資訊的使用者名稱, <password>為該使用者的密碼。
配置項
引數名 說明 預設值
enabled 啟動eureka客戶端 true
registryFetchIntervalSeconds 從eureka服務端獲取註冊資訊系的時間間隔,預設是秒 30
instanceInfoReplicationIntervalSeconds 更新例項資訊的變化到eureka服務端的時間間隔,單位是秒 40
eurekaServiceUrlPollIntervalSeconds 輪詢eureka服務端地址更改的時間間隔,當我們與spring cloud config配合,動態重新整理eureka的serviceUrl地址時候需要關注改引數 300
eurekaServerReadTimeoutSeconds 讀取eureka server資訊的超時時間,單位是秒 8
eurekaServerConnectTimeoutSeconds 連線eureka server的超時時間,單位是秒 5
eurekaServerTotalConnections 從eureka client 到所有eureka server的連線總數 200
eurekaServerTotalConnectionPerHost 從eureka client到 eureka server主機端的最大連線總數 50
eurekaConnectionIdleTimeoutSeconds eureka server連線的空閒關閉時間,單位是秒 30
heartbeatExecotorTheadPoolSize 心跳連線 池的初始化執行緒數 2
heartbeatExecotorExponentialBackOffBouund 心跳超時重試延遲時間的最大乘數值 10
cacheRefreshExecutorThreadPoolSize 快取重新整理執行緒池的初始化執行緒 2
cacheRefreshExecutorExponetialBackOffBound 快取重新整理重試延遲時間的最大乘數值 10
userDnsForFetchingServiceUrls 使用DNS來獲取eureka服務端的serviceUrl false
RegisterWithEureka 是否要將自身的例項資訊註冊到eureka服務端 true
preferSameZoneEureka 是否偏好使用處於相同Zone的eureka client true
filterOnlyUpInstances 獲取例項時是否過濾,僅保留UP狀態的例項 true
fetchRegistry 是否從eureka服務端獲取註冊資訊 true

服務客戶端配置

關於服務客戶端配置,都是以eureka.instance為字首。都是通過eurekaInstanceConfigBean進行載入。
元資料
什麼是元資料:
	就是eureka客戶端向服務註冊中心傳送註冊請求的時候,用來描述自身服務資訊到的物件,
	其中包含一些標準化的元資料,比如服務名稱,例項名稱,例項IP,例項埠等用於服務治理的重要資訊。
	以及一些使用者負載均衡策略或者是其他特殊用途的自定義元資料。
例項名配置
例項名,即InstanceInfo中的instanceId引數,它是區分同一服務中不同例項!的唯一標
識。在Netflix Eureka的原生實現中,例項名採用主機名作為預設值,這樣的設定使得在
同一主機上無法啟動多個相同的服務例項。所以,在Spring Cloud Eureka的配置中,針
對同一主機中啟動多例項的情況,對例項名的預設命名做了更為合理的擴充套件,它採用了
如下預設規則:
${spring.cloud.client.hostname):$(spring. application.name):$(spring.application.
instance id: ${server.port)}
對於例項名的命名規則,我們可以通過eureka.instance.instanceId引數來進行配置。比
如,在本地進行客戶端負載均衡除錯時,需要啟動同一服務的多個例項,如果我們直接啟
動同一個應用必然會產生埠衝突。雖然可以在命令列中指定不同的server.port來啟
動,但是這樣還是略顯麻煩。實際上,我們可以直接通過設定server.port=0或者使用隨機
數server.port=${random.int [10000, 19999]}來讓Tomcat啟動的時候採用隨機埠。但
是這個時候我們會發現註冊到Eureka Server的例項名都是相同的,這會使得只有一個
服務例項能夠正常提供服務。對於這個問題,我們就可以通過設定例項名規則來輕鬆
解決:
eureka.instance.instanceld-$ (spring. application.name):Srandom.int}}
通過上面的配置,利用應用名加隨機數的方式來區分不同的例項,從而實現在同一主機
上,不指定埠就能輕鬆啟動多個例項的效果。
其他配置資訊

在這裡插入圖片描述