## **一、Eureka?詳解**
**\*\*是什么\*\* :**
?? ??? ?Eureka是Netflix開發的服務發現框架,本身是一個基于REST的服務,主要用于定位運行在AWS域中的中間層服務,以達到負載均衡和中間層服務故障轉移的目的。SpringCloud將它集成在其子項目spring-cloud-netflix中,以實現SpringCloud的服務發現功能。
**\*\*有什么\*\* :**
Eureka?主要包含了?Eureka Server和Eureka Client 兩個組件。
**\*\*基本原理\*\* :**
Eureka Server提供服務注冊服務,各個節點啟動后,會在Eureka Server中進行注冊,這樣EurekaServer中的服務注冊表中將會存儲所有可用服務節點的信息,服務節點的信息可以在界面中直觀的看到。
?? ??? ?Eureka Client是一個java客戶端,用于簡化與Eureka Server的交互,客戶端同時也就是一個內置的、使用默認為輪詢(round-robin)負載算法的負載均衡器ribon。
在應用啟動后,將會向Eureka Server發送心跳,默認周期為30秒,如果Eureka Server在多個心跳周期內沒有接收到某個服務節點的心跳,Eureka Server將會從服務注冊表中把這個服務節點移除(默認90秒)。
?? ??? ?Eureka Server集群之間通過復制的方式完成數據的同步,Eureka還提供了客戶端緩存機制,即使所有的Eureka Server都掛掉,客戶端依然可以利用緩存中的信息消費其他服務的API。
?? ??? ?綜上,Eureka通過心跳檢查、客戶端緩存等機制,確保了系統的高可用性、靈活性和可伸縮性。
**ps:原理圖如下**

針對原理圖說明:
**1.注冊、更新(續約)、取消服務:**
注冊: 客戶端充當服務提供者啟動時,會通過 Eureka Client 向 Eureka Server 注冊信息,Eureka Server 會存儲該服務的信息,Eureka Server 內部有二層緩存機制來維護整個注冊表。
更新(續約): 客戶端充當服務提供者默認會每隔 30 秒(可設置)發送一次心跳來續約。 通過續約來告知 服務端注冊中心(Eureka Server) 該 客戶端(Eureka Client)的服務是否 運行正常。
擴展:
默認情況下,若服務端注冊中心(Eureka Server) 在 90 秒內 沒有收到 客戶端(Eureka Client)的續約,服務端注冊中心會將客戶端實例從其注冊表中刪除(服務剔除),此時間可配置,一般情況不建議更改。
Eureka自我保護模式: 為了防止誤殺服務,Eureka Server 在運行期間因網絡問題或服務狀態等原因在統計心跳失敗比例在 15 分鐘之內低于 85%,即固定時間內大量實例被注銷(刪除/下線)則會啟動自我保護模式,提高微服務架構的高可用性。但自我保護模式開啟后會存在以下的問題:
(1 Eureka 不再從注冊列表中移除因為長時間沒收到心跳而應該過期的服務 (2 Eureka 仍然能夠接受新服務的注冊和查詢請求,但是不會被同步到其它節點上(即保證當前節點依然可用 (3 當網絡穩定時,當前實例新的注冊信息會被同步到其它節點中
如果在保護期內剛好這個服務提供者非正常下線了,此時服務消費者就會拿到一個無效的服務實例,即會調用失敗。對于這個問題需要服務消費者端要有一些容錯機制,如重試,斷路器等。
取消: 客戶端(Eureka Client)的服務要關閉時,需通過主動方式向注冊中心發送取消注冊信息的請求進行服務下線,即需在程序中添加以下代碼:DiscoveryManager.getInstance().shutdownComponent();。
**2.更新非己服務列表信息:**
客戶端(Eureka Client)從服務器獲取注冊表信息,并將其緩存在本地。客戶端會使用該信息查找其他服務,從而進行遠程調用。該注冊列表信息定期(每30秒鐘)更新一次。每次返回注冊列表信息可能與 客戶端(Eureka Client) 的緩存信息不同, 客戶端(Eureka Client)自動處理。
如果由于某種原因導致注冊列表信息不能及時匹配, 客戶端(Eureka Client)則會重新獲取整個注冊表信息。 服務端注冊中心(Eureka Server) 的緩存注冊列表信息,整個注冊表以及每個應用程序的信息進行了壓縮,壓縮內容和沒有壓縮的內容完全相同。 客戶端(Eureka Client)和 (Eureka Server)可以使用 JSON/XML 格式進行通訊。在默認情況下 客戶端(Eureka Client)使用壓縮 JSON 格式來獲取注冊列表的信息。
**3.集群節點之間數據信息同步:**
服務端注冊中心(Eureka Server) 集群相互之間通過 Replicate 來同步數據,相互之間不區分主節點和從節點,所有的節點都是平等的。在這種架構中,節點通過彼此互相注冊來提高可用性,每個節點需要添加一個或多個有效的 serviceUrl 指向其他節點。
Eureka集群擴展:
如果某臺 Eureka Server 宕機,Eureka Client 的請求會自動切換到新的 Eureka Server 節點。當宕機的服務器重新恢復后,Eureka 會再次將其納入到服務器集群管理之中。當節點開始接受客戶端請求時,所有的操作都會進行節點間復制,將請求復制到其它 Eureka Server 當前所知的所有節點中。
另外 Eureka Server 的同步遵循著一個非常簡單的原則:只要有一條邊將節點連接,就可以進行信息傳播與同步。所以,如果存在多個節點,只需要將節點之間兩兩連接起來形成通路,那么其它注冊中心都可以共享信息。每個 Eureka Server 同時也是 Eureka Client,多個 Eureka Server 之間通過 P2P 的方式完成服務注冊表的同步。
Eureka Server 集群之間的狀態是采用異步方式同步的,所以不保證節點間的狀態一定是一致的,不過基本能保證最終狀態是一致的。
Eureka 提供了 Region 和 Zone 兩個概念來進行分區,這兩個概念均來自于亞馬遜的 AWS:
region:可以理解為地理上的不同區域,比如亞洲地區,中國區或者深圳等等。沒有具體大小的限制。根據項目具體的情況,可以自行合理劃分 region。
zone:可以簡單理解為 region 內的具體機房,比如說 region 劃分為深圳,然后深圳有兩個機房,就可以在此 region 之下劃分出 zone1、zone2 兩個 zone。
如下圖中的 us-east-1c、us-east-1d、us-east-1e 就代表了不同的 Zone。Zone 內的 Eureka Client 優先和 Zone 內的 Eureka Server 進行心跳同步,同樣調用端優先在 Zone 內的 Eureka Server 獲取服務列表,當 Zone 內的 Eureka Server 掛掉之后,才會從別的 Zone 中獲取信息。

**4.調用服務:**
?? ??? ?充當服務消費者的客戶端會定時從注冊中心中拉取,更新及緩存服務信息列表,當消費者需調用某個服務的時候,則從服務信息列表中獲取相服務的相關信息,比如IP,端口等。
## **二、Eureka?工作流程總結**
1、Eureka Server 啟動成功,等待服務端注冊。在啟動過程中如果配置了集群,集群之間定時通過 Replicate 同步注冊表,每個 Eureka Server 都存在獨立完整的服務注冊表信息
2、Eureka Client 啟動時根據配置的 Eureka Server 地址去注冊中心注冊服務
3、Eureka Client 會每 30s 向 Eureka Server 發送一次心跳請求,證明客戶端服務正常
4、當 Eureka Server 90s 內沒有收到 Eureka Client 的心跳,注冊中心則認為該節點失效,會注銷該實例
5、單位時間內 Eureka Server 統計到有大量的 Eureka Client 沒有上送心跳,則認為可能為網絡異常,進入自我保護機制,不再剔除沒有上送心跳的客戶端
6、當 Eureka Client 心跳請求恢復正常之后,Eureka Server 自動退出自我保護模式
7、Eureka Client 定時全量或者增量從注冊中心獲取服務注冊表,并且將獲取到的信息緩存到本地
8、服務調用時,Eureka Client 會先從本地緩存找尋調取的服務。如果獲取不到,先從注冊中心刷新注冊表,再同步到本地緩存
9、Eureka Client 獲取到目標服務器信息,發起服務調用
10、Eureka Client 程序關閉時向 Eureka Server 發送取消請求,Eureka Server 將實例從注冊表中刪除