1. 程式人生 > 其它 >【SpringCloud】筆記——Eureka

【SpringCloud】筆記——Eureka

技術標籤:SpringCloud筆記javaspringeureka

【SpringCloud】筆記——Eureka

Eureka是Spring Cloud Netflix微服務套件中的一部分,主要任務是在微服務架構中提供服務治理的功能。Spring Cloud中的Eureka針對Spring Boot應用風格進行了適配,從而可以更加方便地將Eureka服務治理體系應用到基於Spring Boot構建的微服務應用中去。

說到服務治理,就得提一下微服務架構。微服務架構將傳統單體系統分解成了多個微服務元件,每一個微服務元件可以單獨進行開發除錯,並且可以部署到不同的位置通過RPC進行遠端呼叫。那麼為什麼要進行服務治理,如果只是很少的幾個微服務,那麼確實簡單的靜態配置就可以將這些微服務整合起來構成一個具有一定功能的系統,但是我們的系統是在不斷迭代的,越來越多的微服務元件會被加入進來,同時之前的微服務配置資訊還會有所變化,可想而知,一旦微服務數量上來,系統變複雜,那麼維護這些微服務的配置將會非常困難,而Eureka正是這樣一個專門用於管理微服務的利器。

Eureka服務治理體系中包含三個核心要素:服務註冊中心、服務提供者和服務消費者。

  • 服務註冊中心

服務註冊中心是由Eureka提供的客戶端,主要用於服務的註冊與發現功能,其相當於微服務架構中的管理中心。比如你開發了一個微服務想要提供出來,那麼你就需要向註冊中心註冊你的服務,如果你想要呼叫一個特定的微服務,那麼你首先需要向註冊中心提交申請。打個比方的話,就類似於拍賣行一樣,不管你是買東西還是賣東西,都得過來登記一下,拍賣行(註冊中心)負責管理商品資訊(微服務配置)以及撮合買賣交易(微服務的呼叫)。

搭建一個服務註冊中心的過程也比較簡單,首先在pom檔案裡新增Eureka相關依賴,然後在啟動應用的類上新增@EnableEurekaServer註解即可,該註解的功能就是啟動一個服務註冊中心。在application.properties裡可以配置一些相關引數,比如:

server.port=1234   
eureka.instance.hostname=localhost
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
eureka.client.serviceUrl.defaultZone=http://${eureka.instance.hostname}:{server.port}/eureka/

其中register-with-eureka表示是否要向註冊中心註冊自己,預設是註冊的,也就是預設你是一個服務提供者,而單獨存在的註冊中心並不需要向自己註冊,所以設為false。fetch-registry表示是否要檢索服務,預設是檢索的。這兩項預設為true是因為大多數情況下,一個微服務中還會呼叫其他的微服務,因此對於註冊中心來說,它即是服務提供者,又是服務消費者。

服務治理不僅包含了對於微服務配置的管理,同時還包含了對於大量服務呼叫請求下的高可用問題。微服務架構本身就屬於分散式架構,考慮到微服務節點以及註冊中心本身都存在故障的可能,因此我們經常部署多個服務註冊節點來增強可用性。通過構建多個服務註冊中心,將defaultZone標記為其他註冊中心,並將上面提到的引數設為true,便可以搭建起多個註冊中心的叢集。就和一個區域網內部的路由器之間會相互同步更新路由資訊一樣,叢集中的註冊中心節點也會通過一定的策略互相更新服務註冊資訊來保持高可用。

除此之外,註冊中心還有失效剔除和自我保護等功能。已經註冊的服務會維持一個心跳連線時不時得告訴註冊中心自己還活著,有時由於一些異常故障等原因,已經註冊的服務可能會突然下線,為了將這些失效任務及時清理掉,Eureka會建立一個定時任務每隔一段時間去清理沒有續約的服務。為了防止誤傷網路原因導致的心跳未傳達,Eureka還會統計15分鐘內的心跳失敗比率,如果低於85%的話,那麼Eureka會認為不是服務掛了,而是網路不穩定,然後將該服務保護起來不進行剔除。

  • 服務提供者

服務提供者是被呼叫的一方,想要被呼叫首先需要向服務註冊中心註冊自己,上文中的register-with-eureka和fetch-registry屬性預設true就可以。除此之外,還需要在相關介面中利用@Autowired注入一個DiscoveryClient物件,這個物件是由Eureka實現的,再在主類上新增@EnableDiscoveryClient註解便可以啟用該例項。服務名稱在配置檔案中根據spring.application.name來命名,defaultZone指向要註冊的註冊中心地址即可。註冊完成之後分別啟動註冊中心和相應服務便可以在控制檯看到輸出資訊,在Eureka的控制面板裡也可以看到相應資訊。

在註冊服務時,一般是通過傳送REST請求的方式來將自己註冊到註冊中心的,請求中還會包含一些元資料資訊。註冊中心一般將這些元資料資訊儲存在一個雙層Map中,第一層key是服務名,第二層key是例項名,即呼叫服務時,註冊中心會首先根據服務名稱來確定其對應的例項集合,然後再從中挑選一個例項取出。註冊完成後,為了防止註冊中心把自己剔除掉,還需要維護一個心跳來告訴註冊中心自己一直活著,對於該功能可以進行如下配置:

eureka.instance.lease-remewal-interval-in-seconds=30
eureka.instance.lease-expiration-duration-in-seconds=90

其中lease-remewal-interval-in-seconds表示服務續約任務的間隔時間,lease-expiration-duration-in-seconds表示服務失效的時間。

  • 服務消費者

服務消費者是呼叫服務的一方,在微服務架構中想要呼叫微服務需要向註冊中心提交申請,服務的發現與消費除了Eureka以外還有Ribbon的參與,Eureka負責發現對應的服務,Ribbon則負責從相應服務例項中進行選擇。服務消費者的配置和上述服務提供者基本一直,也是新增@EnableDiscoveryClient註解,注入DisvoveryClient例項來發現服務。@LoadBalanced註解可以實現客戶端的負載均衡,這個功能需要新增對Ribbon的依賴。這樣便可以在相應方法內通過之前註冊的服務名稱來進行呼叫了。

在註冊中心收到消費方的請求時,會返回其一個只讀的服務清單列表,這個列表裡包含了呼叫服務的相關資訊,該清單會進行快取,每隔30秒更新一次。這個間隔時間可以通過修改如下引數來調整:

eureka.client.registry-fetch-interval-seconds=30

當某個服務關閉或者重啟時,關閉期間會觸發一個服務下線的通知,該通知以REST請求的形式傳送給註冊中心,表明自己要下線了。然後註冊中心便會將其狀態設定為DOWN,如果有叢集的話,還會在叢集中將該事件傳播出去。

最後列具一下Eureka相關的詳細配置引數。

以eureka.client為字首的:

引數名說明預設值
enabled啟用Eureka客戶端true
registryFetchIntervalSeconds從Eureka服務端獲取註冊資訊的間隔時間,單位為秒30
instanceInfoReplicationIntervalSeconds更新例項資訊的變化到Eureka服務端的間隔時間,單位為秒30
initialInstanceInfoReplicationIntervalSeconds初始化例項資訊到Eureka服務端的間隔時間,單位為秒40
eurekaServiceUrlPollIntervalSeconds輪詢Eureka服務端地址更改的間隔時間,單位為秒300
eurekaServerReadTimeoutSeconds讀取Eureka Server資訊的超時時間,單位為秒8
eurekaServerConnectTimeoutSeconds連線Eureka Server的超時時間,單位為秒5
eurekaServerTotalConnections從Eureka客戶端到所有Eureka服務端的連線總數200
eurekaServerTotalConnectionsPerHost從Eureka客戶端到每個Eureka服務端主機的連線總數50
eurekaConnectionIdleTimeoutSecondsEureka服務端連線的空閒關閉時間,單位為秒30
heartbeatExecutorThreadPoolSize心跳連線池的初始化執行緒數2
heartbeatExecutorExponentialBackOffBound心跳超時重試延遲時間的最大乘數值10
cacheRefreshExecutorThreadPoolSize快取刷洗執行緒池的初始化執行緒數2
cacheRefreshExecutorExponentialBackOffBound快取重新整理重試延遲時間的最大乘數值10
useDnsForFetchingServiceUrls使用DNS來獲取Eureka服務端的serviceUrlfalse
registerWithEureka是否要將自身的例項資訊註冊到Eureka服務端true
preferSameZoneEureka是否偏好使用處於相同Zone的Eureka服務端true
filterOnlyUpInstances獲取例項時是否過濾,僅保留UP狀態的例項true
fetchRegistry是否從Eureka服務端獲取註冊資訊true

以eureka.instance為字首的:

引數名說明預設值
preferIpAddress是否優先使用IP地址作為主機名的標識false
leaseRenewalIntervalInSecondsEureka客戶端向服務端傳送心跳的時間間隔,單位為秒30
leaseExpirationDurationInSecondsEureka服務端在收到最後一次心跳之後等待的時間上限,單位為秒90
nonSecurePort非安全的通訊埠號80
securePort安全的通訊埠號443
nonSecurePortEnabled是否啟用非安全的通訊埠號true
securePortEnabled是否啟用安全的通訊埠號
appname服務名,預設取spring.application.name的配置值,沒有則為unknown
hostname主機名,不配置的時候將根據作業系統的主機名來獲取