Eureka 系列(02)Eureka 一致性協議


Eureka 系列(02)Eureka 一致性協議

Eureka 是由 Netflix 基於 AP 模型的服務發現中間件,包括服務發現服務器和客戶端的。相關文檔推薦:一是 Spring Cloud Eureka 官網,二是 Eureka源碼解析

本系列源碼分析基於 spring-cloud-starter-netflix-eureka-2.1.1.RELEASE 和 Eureka-1.9.8。

0. Spring Cloud 系列目錄 - Eureka 篇

1. 服務發現方案對比

1.1 技術選型

表1:Spring Cloud 服務發現方案對比
技術選型 CAP模型 適用規模(建議) 控制台管理 社區活躍度
Eureka AP <30k 支持
Zookeeper CP <20k 不支持
Consul AP <5k 支持
Nacos AP/CP 100k+ 支持 靠大家啦☺

注: 以上數據來源於 小馬哥技術周報

1.2 數據模型

表2:Spring Cloud 服務發現數據模型
框架 集群(框架) 服務應用 服務集群 服務實例 租約管理
Spring-Cloud -- (serviceId) -- ServiceInstance --
Nacos Server Service Cluster Instance --
Eureka (serviceUrl) Application(appName) -- InstanceInfo(id) Lease

不同的框架對應的數據結構不太一致,在此做一些約定:

  1. 服務器集群 Server:指的是 Eureka Server 本身的集群。用 Server 代替,也可能是 ServerList 之類,總之與 Server 或 Peer 或 Node 相關的都代表框架自身的集群。
  2. 服務 Service:代表一個應用,可能包含多個服務實例。 Service(服務)serviceIdApplication(應用)appName
  3. 集群 Cluster:一個 Service 可能包含多個 Cluster,Cluster 包含多個具體的實例。這是 Nacos 中的概念。
  4. 服務實例 ServiceInstance:代表注冊的一個具體實例。ServiceInstance(服務實例)InstanceInfo(實例id)Instance(實例)

2. Eureka 一致性協議

Eureka 和 Zookeeper 的最大區別: Eureka 是 AP 模型,Zookeeper 是 CP 模型。在出現腦裂等場景時,Eureka 可用性是每一位,也就是說出現腦裂時,每個分區仍可以獨立提供服務,是去中心化的。更多 Eureka與ZooKeeper 的比較

那 Eureka 是如何實現最終一致性的呢?

2.1 消息廣播

  1. Eureka Server 管理了全部的服務器列表(PeerEurekaNodes)

  2. 當 Eureka Server 收到客戶端的注冊、下線、心跳請求時,通過 PeerEurekaNode 向其余的服務器進行消息廣播,如果廣播失敗則重試,直到任務過期后取消任務,此時這兩台服務器之間數據會出現短暫的不一致。

    注意: 雖然消息廣播失敗,但只要收到客戶端的心跳,仍會向所有的服務器(包括失聯的服務器)廣播心跳任務。

  3. 如果網絡恢復正常,收到了其它服務器廣播的心跳任務,此時可能有三種情況:

    1. 一是腦裂很快恢復,一切正常;
    2. 二是該實例已經自動過期,則重新進行注冊;
    3. 三是數據沖突,出現不一致的情況,則需要發起同步請求,其實也就是重新注冊一次,同時踢除老的實例。

    總之,通過集群之間的消息廣播可以實現數據的最終一致性。

2.1.2 服務注冊

  1. Spring Cloud Eureka 在應用啟動時,會在 EurekaAutoServiceRegistration 這個類初始化的時候,主動去 Eureka Server 端注冊。
  2. Eureka 在啟動完成之后會啟動一個 40 秒執行一次的定時任務,該任務會去監測自身的 IP 信息以及自身的配置信息是否發生改變,如果發生改變,則會重新發起注冊。
  3. 續約返回 404 狀態碼時,會去重新注冊

2.1.3 主動下線

Eureka 會在 spring 容器銷毀的時候執行 shutDown 方法 ,該方法首先會將自身的狀態改為 DOWN,接着發送cancle 命令至 Eureka Server 請求下掉自己的服務。

2.1.4 心跳續約與自動下線

健康檢測,一般都是 TTL(Time To Live) 機制。eg: 客戶端每 5s 發送心跳,服務端 15s 沒收到心跳包,更新實例狀態為不健康, 30s 未收到心跳包,從服務列表中刪除。

Eureka Server 默認每 30s 發送心跳包,90s 未收心跳則刪除。這個清理過期實例的線程,每 60s 執行一次。

2.2 崩潰恢復

2.2.1 重啟

Spring Cloud Eureka 啟動時,在初始化 EurekaServerBootstrap#initEurekaServerContext 時會調用 PeerAwareInstanceRegistryImpl#syncUp 從其它 Eureka 中同步數據。

2.2.2 腦裂

  • 發生腦裂后:和 Eureka Server 同區的服務可以正常訪問,而不同區的服務則自動過期。
  • 腦裂恢復后:接收其它 Eureka Sever 發送過來的心跳請求,此時有三種情況:一是腦裂很快恢復,一切正常;二是該實例已經自動過期,則重新進行注冊;三是數據沖突,出現不一致的情況,則需要發起同步請求。

3. 可靠性

3.1 高可用客戶端(Client HA)

當有多個 Eureka Server 時,第一台宕機時會從下一台同步數據。注意:只有當第一台宕機時才會同步第二台,否則永遠只會從第一台同步數據。

3.2 自我保護

如果每分鍾的續約數小於閥值時 ,則開啟自我保護機制,Eureka Server 將不會主動清除過期實例。


每天用心記錄一點點。內容也許不重要,但習慣很重要!


免責聲明!

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



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