【Spring Cloud(二)】服務注冊與發現組件Eureka


一、Eureka原理

1、架構圖

首先來看eureka的官方結構圖

  所有應用作為Eureka Client和Eureka Server交互,服務提供者啟動時向Eureka Server注冊自己的IP、端口、提供服務等信息,並定時續約更新自己的狀態。

  服務消費者通過Eureka Server發現得到所需服務的提供者地址信息,然后向服務提供者發起遠程調用。

  為了保證Eureka注冊中心的高可用,可以集群部署,其中一個節點信息又更新時通知其他Server節點,不同節點的Eureka通過Replicate進行數據同步。

2、基本原理

在Eureka響應的過程中,有三個角色,分別是Eureka、服務提供者、服務消費者;

  • 在服務啟動后,服務提供者向Eureka注冊自己的信息,如調用地址、提供服務信息等
  • Eureka為服務注冊中心,向外暴露自己的地址,負責管理、記錄服務提供者的信息,同時將符合要求的服務提供者地址列表返回服務消費者
  • 服務消費者向Eureka訂閱服務,表達自己的需求,然后得到服務提供者消息,遠程調用即可

Eureka包含兩個組件:Eureka Server和Eureka Client,作用如下:

  • Eureka Client是一個Java客戶端,主要用來簡化和Eureka Server的交互
  • Eureka Server提供服務發現的能力,各個微服務啟動時,通過Eureka Client向Eureka Server注冊自己的信息,Server儲存該服務的信息
  • 微服務啟動后,周期性(默認為30s)地向Server發送心跳信息,以續約自己的信息,超時(默認為90s)未接受到心跳信息,Server將注銷該服務節點
  • 在Eureka Server設置注銷某個服務提供者節點后,並將該服務向其他訂閱者發布,訂閱者更新本地緩存信息
  • 在集群中,每個Eureka Server同時也是Eureka Client,互相注冊完成服務注冊表的消息同步,避免因為某個Eureka節點掛掉而導致整個微服務架構掛掉
  • Eureka Client會緩存Server中的信息,在調用服務前,首先查看緩存是否存在相關信息,本地的緩存定期更新

3、自我保護機制

   由於在超時(默認90s)未接受到服務提供者的心跳續約信息后,Eureka Server就注銷該實例,但往往由於微服務之間的跨進程調用,受網絡通信情況影響較大,比如在微服務狀態正常,但網絡分區故障時,注銷服務實例會讓大部分微服務不可用,為避免這樣的情況,引進了Eureka的自我保護機制。自我保護機制的原理是,當某個Eureka Server節點在短時間內丟失了過多的客戶端節點時,該節點就進入自我保護機制,不再注銷任何微服務實例,當網絡故障恢復正常后,該節點自動退出自我保護機制。

  自我保護機制根據自我保護閾值來區分是Eureka Server還是Eureka Client出了問題導致服務未能按時續約。

4、服務機制

   一個服務按流程依次為服務注冊,然后周期性地續約服務,若服務正常停止,則在停止服務之前向注冊中心發送注銷請求,若為非正常停止,則不會發送,該服務由Eureka Server主動剔除。

4.1、服務注冊機制——Register

在服務提供者啟動時用來注冊服務,以及提供者狀態發生變化時更新服務狀態。

server接受服務注冊后,首先保存注冊信息;然后更新自我保護閾值,供服務剔除機制使用;最后同步服務信息,將此事件同步至其他Eureka Server節點。

4.2、服務續約機制——Renew

由服務提供者定期調用,向server發送心跳信息續約服務。

在注冊中心接受到續約請求后,更新服務對象的最近續約時間,然后同步服務信息,將此事件同步至其他Eureka Server節點。

剔除服務之前會首先判斷服務是否過期,是否過期的條件之一就是最近續約時間和當前時間差值是否大於閾值。

4.3、服務注銷機制——Cancel

由服務提供者shut down時調用,用來注銷自己的服務。

類似注冊機制,在注冊中心接受到cancel請求后,首先刪除服務信息,然后更新(剔除服務)閾值,最后同步該事件到其他Eureka Server節點。

4.4、服務剔除機制——Eviction

  服務剔除包括三個步驟,首先判斷是否滿足服務剔除的條件,然后找出過期的服務,最后執行服務的剔除。

判斷是否滿足服務剔除的條件——主要看Eureka是否開啟自我保護機制

  關閉自我保護機制的情況下,直接進入下一步;

  開啟自我保護機制的情況下,只有實際續約數大於自我保護閾值(說明大部分服務可用,判斷Client出了問題,反之判斷為Server出了問題),才會進入服務剔除流程。

  自我保護閾值=服務總數*(60s / 客戶端續約間隔)*自我保護閾值因子。

找出過期的服務

  遍歷所有服務,判斷最近續約時間距離當前時間差值大於設定的閾值,就標記為過期,並將所有過期的服務保存到集合中。

剔除服務

  遍歷所有過期服務,通過洗牌算法確保每次都公平地選擇出要剔除的服務,最后進行剔除。

4.5、拉取服務——Fetch Registries

由服務消費者調用,發現注冊中心同名服務列表。

通常服務提供者地址信息列表會在本地緩存一份,默認每30s更新一次緩存信息。

4.6、服務同步——Replicate

用來實現Server之間的服務信息同步,服務提供者僅需在一個server注冊就可在server集群中更新信息。

接受注冊請求的節點將請求再次轉發到其他的server節點,調用接口和參數等完全相同,除了標記isReplicate=true,避免重復的同步Replicate。

信息同步為異步方式完成,所有不保證節點信息的強一致性,只能保證最終一致。

4.7、新節點的加入(New Server Initialize)

新的server節點加入,啟動時將自己作為消費者,拉取所有已注冊信息,然后將每個服務注冊到自身節點,標記isReplicate=true,完成初始化。

4.8、存儲結構——兩層Hash Map

二、服務注冊中心的選擇

1、CAP原則

  CAP定理:在一個分布式系統中,一致性(Consistency)、可用性(Availability)、分區容錯性(Partition tolerance),三者不可同時獲得。

  • 一致性:在分布式系統中,所有數據備份在同一時刻是否為同樣的值
  • 可用性:集群中一部分節點故障后,該集群還能否正常響應客戶端的讀寫請求
  • 分區容錯性:一個節點故障掛掉后,不影響其他節點的正常使用,即高可用性

  CAP理論說明在一個分布式系統中,最多同時實現其中的兩點,而由於當前的網絡硬件必然會出現延遲丟包的問題,所以分區容錯性是必要的,所以只能在一致性和可用性中間權衡。

2、注冊中心的選擇

  目前主流的注冊中心有Eureka、Zookeeper、consul等,各自的側重點不同。

2.1、Zookeeper保證CP

  Zookeeper在master節點因為網絡故障而與其他節點失去聯系后,剩余節點會重新進行leader節點的選舉,而在選舉期間(30~120s),整個zk集群都是不可用的,雖然服務最終也能恢復,但是漫長的選舉時間導致注冊中心經常長期不可用卻是不能容忍的。

2.2、Consul保證CP

  Consul強一致性帶來的是:服務注冊要比Eureka慢,因為consul的raft協議要求必須過半數的節點都寫入成功才認為是注冊成功;當Leader節點掛掉后,重新選舉期間整個consul不可用,犧牲了集群的可用性。

2.3、Eureka保證AP

  Eureka在設計時優先保證可用性,其中各個節點都是平等的,幾個節點掛掉,剩余節點仍能提供注冊和查詢服務,只要有一台Eureka還在,就能保證服務可用(保證可用性),但不保證查詢到的信息時最新的(不保證強一致性);除此之外,由於自我保護機制不再剔除服務實例的節點,仍能接受新服務的注冊和查詢請求,但不會被同步到其他節點上。

  同時,Eureka還提供客戶端(Eureka客戶端程序負責向外提供注冊與發現服務接口)緩存功能,所以極端情況下,客戶端無法訪問任何一個Server節點,消費者仍能通過客戶端查詢與獲取注冊服務信息。

  因此,Eureka可以很好地應對因網絡故障導致部分節點失聯的情況,盡可能地保證整個集群的可用性。

三、demo工程的搭建

新建maven工程,刪除src文件夾,作為項目運行環境。

1、server節點

新建module名為Server_1,為標准的SpringBoot工程,其目錄結構如下。

在pom文件中添加Eureka-server和Eureka-client依賴。

啟動類上添加@EnableEurekaServer注解,標注為Eureka Server節點。

在配置文件中增加相關配置信息。

server.port暴露服務端口。

spring.application.name為應用名,應用名為SpringCloud中服務調用的依據。(注:應用名中不可有下划線,否則會調用失敗。)

eureka屬性有server、client、instance等部分;

  client.register-with-eureka為是否將應用注冊到eureka,默認為true,單點server節點指定為false

  client.fetch-registry為是否從注冊中心拉取已注冊信息,默認為true,單點server節點指定為false

  client.service-url.defaultZone指定注冊中心地址

啟動應用,訪問localhost:1001/即可看到eureka注冊中心服務管理界面。

2、服務提供者——Hello_1

新建module名為Hello_1,SpringBoot工程,提供常規的SpringMVC訪問控制,目錄結構如下。

 添加Eureka-server和Eureka-client依賴。

啟動類添加@EnableDiscoveryClient注解,使用@EnableEurekaClient效果一樣。

service和controller包中提供MVC的服務實現與訪問控制功能。

在配置文件application.yml中,添加相關配置,將該應用注冊到之前的Eureka Server節點,注冊名為hello-app。

啟動應用后,訪問localhost:1001/即可看到剛注冊的應用。

3、服務消費者——Introduce

 繼續新建module名為Introduce,調用hello-app服務。

目錄結構仍為SpringBoot工程,實現SpringMVC訪問控制。

除了添加Eureka的依賴外,添加Ribbon依賴(客戶端負載均衡,后續要用到)。

啟動類上加入@EnableEurekaClient注解,並注入RestTemplate Bean,添加@LoadBalanced注解,表明開啟負載均衡功能。

controller包內提供訪問控制。

 

service包內提供服務的具體實現,此處為對hello-app應用的遠程調用,通過構造url,利用RestTemplate發起RestFul請求。

訪問的URL構造為http://${請求應用名}/${請求路徑}?${可能的參數列表}

不要忘記在配置文件中增加相關配置信息。

 啟動應用后,訪問localhost:1001/查看應用注冊情況,訪問localhost:8001/intro?name=world查看服務調用結果。

 

至此,完成了一個單點EurekaServer環境的搭建,並在其上注冊兩個應用,實現服務間的遠程調用。


免責聲明!

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



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