SpringCloud之Eureka
推薦參考:https://www.springcloud.cc/spring-cloud-dalston.html#_service_discovery_eureka_clients
1. 什么是Eureka
-
Eureka 用于簡化分布式系統的服務治理,基于REST的服務,用于服務的注冊與發現。通過注冊發現、客戶端負載均衡和故障轉移機制,提升中間層服務的彈性與可維護性。有了服務注冊與發現,只需要使用服務的標識符,就可以訪問到服務,而不需要修改服務調用的配置文件了。 其設計優先保障可用性(AP 模型),尤其適合云環境中動態伸縮的服務架構。在 Spring Cloud 生態中,它已成為微服務基礎設施的關鍵組件。
2. 核心作用
-
服務注冊與發現
服務注冊:服務提供者(Provider)啟動時,將自身信息(如 IP、端口、服務名)注冊到 Eureka Server,形成服務注冊表。
服務發現:服務消費者(Consumer)通過 Eureka Server 查詢并獲取目標服務的可用實例列表,基于本地緩存實現快速調用。
動態更新:客戶端每 30 秒拉取一次服務注冊表,確保信息時效性。
-
中間層負載均衡
針對微服務架構中的中間層服務(如數據庫訪問層、業務邏輯層),提供客戶端負載均衡能力,支持輪詢等基礎算法。
與 AWS ELB(面向終端 Web 流量)互補,解決 AWS 環境下中間層服務暴露的安全性問題。
-
故障轉移與健康監測
心跳機制:服務實例每 30 秒向 Eureka Server 發送心跳。若 90 秒未收到心跳,則自動剔除該實例。
故障切換:消費者通過本地緩存的服務列表,自動切換到健康實例,避免單點故障影響系統可用性。
3. 基本架構
-
Springcloud 封裝了Netflix公司開發的Eureka模塊來實現服務注冊與發現.
-
Eureka采用了 C-S 的架構設計,Eureka Server作為服務注冊功能的服務器,他是服務注冊中心.
而系統中的其他微服務,使用Eureka的客戶端連接到Eureka Server并維持心跳連接。這樣系統的維護人員就可以通過Eureka Server來監控系統中各個微服務是否正常運行,Springcloud 的一些其他模塊 (比如Zuul) 就可以通過Eureka Server來發現系統中的其他微服務,并執行相關的邏輯. -
Eureka 包含兩個組件:Eureka Server 和 Eureka Client:
Eureka Server 提供服務注冊,各個節點啟動后,回在Eureka Server中進行注冊,這樣Eureka Server中的服務注冊表中將會儲存所有課用服務節點的信息,服務節點的信息可以在界面中直觀的看到.
Eureka Client 是一個Java客戶端,用于簡化Eureka Server的交互,客戶端同時也具備一個內置的,使用輪詢負載算法的負載均衡器。在應用啟動后,將會向Eureka Server發送心跳(默認周期為30秒) 。如果Eureka Server在多個心跳周期內沒有接收到某個節點的心跳,Eureka Server將會從服務注冊表中把這個服務節點移除掉 (默認周期為90s).
-
三大角色:
Eureka Server:提供服務的注冊與發現
Service Provider:服務生產方,將自身服務注冊到Eureka中,從而使服務消費方能夠找到
Service Consumer:服務消費方,從Eureka中獲取注冊服務列表,從而找到消費服務
4. 自我保護機制
.
默認情況下,當Eureka Server在一定時間內沒有收到實例的心跳,便會把該實例從注冊表中刪除
(默認是90秒),但是,如果短時間內丟失大量的實例心跳,便會觸發Eureka Server的自我保護機
制,比如在開發測試時,需要頻繁地重啟微服務實例,但是我們很少會把Eureka Server一起重啟
(因為在開發過程中不會修改Eureka 注冊中心),當一分鐘內收到的心跳數大量減少時,會觸發該
保護機制。可以在Eureka 管理界面看到Renews threshold和Renews(last min),當后者(最后一分鐘
收到的心跳數)小于前者(心跳閾值)的時候,觸發保護機制,會出現紅色的警告:
EMERGENCY!EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN
THEY’RE NOT.RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES
ARE NOT BEGING EXPIRED JUST TO BE SAFE.
從警告中可以看到,Eureka 認為雖然收不到實例的心跳,但它認為實例還是健康的,Eureka 會保護這些實例,不會把它們從注冊表中刪掉。
該保護機制的目的是避免網絡連接故障,在發生網絡故障時,微服務和注冊中心之間無法正常通
信,但服務本身是健康的,不應該注銷該服務,如果Eureka因網絡故障而把微服務誤刪了,那即使
網絡恢復了,該微服務也不會重新注冊到Eureka Server了,因為只有在微服務啟動的時候才會發起
注冊請求,后面只會發送心跳和服務列表請求,這樣的話,該實例雖然是運行著,但永遠不會被其
它服務所感知。所以,Eureka Server在短時間內丟失過多的客戶端心跳時,會進入自我保護模式,
該模式下,Eureka 會保護注冊表中的信息,不在注銷任何微服務,當網絡故障恢復后,Eureka 會自動退出保護模式。自我保護模式可以讓集群更加健壯。
但是我們在開發測試階段,需要頻繁地重啟發布,如果觸發了保護機制,則舊的服務實例沒有被刪
除,這時請求有可能跑到舊的實例中,而該實例已經關閉了,這就導致請求錯誤,影響開發測試。
所以,在開發測試階段,我們可以把自我保護模式關閉,只需在Eureka server配置文件中加上如下
配置即可:eureka.server.enable-self-preservation=false【不推薦關閉自我保護機制】
5. 主流注冊中心對比(Eureka,Consul,Zookeeper,Nacos)
.
根據CAP原理,將NoSQL數據庫分成了滿足CA原則,滿足CP原則和滿足AP原則三大類, CAP理論
指出,一個分布式系統不可能同時滿足C (一致性) 、A (可用性) 、P (容錯性),由于分區容錯性P再分布式系統中是必須要保證的,因此我們只能再A和C之間進行權衡。
CA:單點集群,滿足一致性,可用性的系統,通常可擴展性較差
CP:滿足一致性,分區容錯的系統,通常性能不是特別高
AP:滿足可用性,分區容錯的系統,通常可能對一致性要求低一些
對比圖表:
注冊中心 | CAP模型 | 一致性協議 | 設計側重點 | 典型適用場景 |
---|---|---|---|---|
Eureka | AP | 自定義復制協議 | 高可用性、最終一致性 | Netflix 生態、Spring Cloud 體系、容忍短暫不一致的云原生環境 |
Consul | CP | Raft | 強一致性、多數據中心支持 | 金融、政務等強一致需求場景;多數據中心管理 |
Zookeeper | CP | ZAB(類Paxos) | 強一致性、順序一致性 | 分布式協調場景(如Kafka、Hadoop)、分布式鎖、選主 |
Nacos | 混合模式(AP/CP可切換) | Distro(AP)Raft(CP) | 靈活適配、臨時實例AP/持久實例CP | 全場景覆蓋,微服務注冊發現與配置中心;動態切換需求 |
6. 問:作為分布式服務注冊中心,Eureka比Zookeeper好在哪里?
.
答:
Zookeeper保證的是CP:
當向注冊中心查詢服務列表時,我們可以容忍注冊中心返回的是幾分鐘以前的注冊信息,但不能接收服務直接down掉不可用。也就是說,服務注冊功能對可用性的要求要高于一致性。但zookeeper會出現這樣一種情況,當master節點因為網絡故障與其他節點失去聯系時,剩余節點會重新進行leader選舉。問題在于,選舉leader的時間太長,30-120s,且選舉期間整個zookeeper集群是不可用的,這就導致在選舉期間注冊服務癱瘓。在云部署的環境下,因為網絡問題使得zookeeper集群失去master節點是較大概率發生的事件,雖然服務最終能夠恢復,但是,漫長的選舉時間導致注冊長期不可用,是不可容忍的。
Eureka保證的是AP:
Eureka看明白了這一點,因此在設計時就優先保證可用性。Eureka各個節點都是平等的,幾個節點掛掉不會影響正常節點的工作,剩余的節點依然可以提供注冊和查詢服務。而Eureka的客戶端在向某個Eureka注冊時,如果發現連接失敗,則會自動切換至其他節點,只要有一臺Eureka還在,就能保住注冊服務的可用性,只不過查到的信息可能不是最新的,除此之外,Eureka還有之中自我保護機制,如果在15分鐘內超過85%的節點都沒有正常的心跳,那么Eureka就認為客戶端與注冊中心出現了網絡故障,此時會出現以下幾種情況:
- Eureka不在從注冊列表中移除因為長時間沒收到心跳而應該過期的服務
- Eureka仍然能夠接受新服務的注冊和查詢請求,但是不會被同步到其他節點上 (即保證當前節點依然可用)
- 當網絡穩定時,當前實例新的注冊信息會被同步到其他節點中。
因此,Eureka可以很好的應對因網絡故障導致部分節點失去聯系的情況,而不會像zookeeper那樣使整個注冊服務癱瘓。