1、什麼是Eurekajava
Eureka是Netflix公司開源的產品,它是一種基於REST( Representational State Transfer )的服務,主要用於AWS雲。 Eureka提供了完整的Service Registry和Service Discovery實現實現,也是Spring Cloud體系中最重要的組件之一。spring
簡單來講Eureka就是Netflix開源的一款提供服務註冊和發現的產品,而且提供了java客戶端。固然,springcloud大力優化後的Eureka,能夠應用在任何須要使用註冊中心的場景。數據庫
Eureka由兩個組件組成:Eureka服務端和Eureka客戶端。Eureka服務端就是註冊中心。Eureka客戶端是一個java客戶端,用來簡化與服務端的交互、做爲輪詢負載均衡器,並提供服務的故障切換支持。緩存
下面是Eureka的使用場景安全
從上面看Eureka Server擔任註冊中心的角色,提供了服務的發現和註冊功能。服務器
Service Provider服務提供者,將自身的服務註冊到Eureka Server,同時經過心跳檢查服務的運行狀態。網絡
Service Consumer服務調用者,從Eureka Server獲得註冊的服務列表,找到對應的服務地址調用並使用。數據結構
2、Eureka核心概念架構
一、Eureka Server:註冊中心服務端app
註冊中心服務端主要對外提供了三個功能:
(1)服務註冊
服務提供者啓動時,會經過Eureka Client向Eureka Server註冊信息,Eureka Server會存儲該服務的信息,Eureka Server內部有二層緩存機制來維護整個註冊表。
(2)提供註冊表
服務消費者在調用服務時,若是Eureka Client沒有緩存註冊表的話,會從Eureka Server獲取最新的註冊表。
(3)同步狀態
Eureka Client經過註冊、心跳機制和Eureka Server同步當前客戶端的狀態。
二、Eureka Client:註冊中心客戶端
Eureka Client是一個java客戶端,用於簡化與Eureka Server的交互。Eureka Client會拉取、更新、緩存Eureka Server中的信息。所以當全部的Eureka Server節點都宕掉,服務消費者依然可使用緩存中的信息找到服務的提供者,可是當服務有更改的時候會出現信息不一致。
三、Register:服務註冊
服務的提供者,將自身註冊到註冊中心,服務提供者也是一個Eureka Client。當Eureka Client向Eureka Server註冊時,它提供自身的元數據,好比IP地址、端口、運行情況指示符URL、主頁等。
四、Renew:服務續約
Eureka Client會每隔30秒發送一次心跳來續約。經過續約來告知Eureka Server該Eureka Client運行正常,沒有出現問題。默認狀況下,若是Eureka Server在90秒內沒有收到Eureka Client的續約,Server端會將實例從其註冊表中刪除,此事件可配置,通常狀況不建議更改。
五、Eviction服務剔除
當Eureka Client和Eureka Server再也不有心跳時,Eureka Server會將服務實例從服務註冊列表中刪除,即服務剔除。
六、Cancel:服務下線
Eureka Client在程序關閉時想Eureka Server發送取消請求,發送請求後,該客戶端實例信息將從Eureka Server的實例註冊表中刪除。該下線請求不會自動完成,它須要調用一下內容:
DiscoveryManager.getInstance().shutdownComponent();
七、GetRegistry:獲取註冊列表信息
Eureka Client從服務器獲取註冊表信息,並將其緩存在本地。客戶端會使用該信息查找其餘服務,從而進行遠程調用。該註冊列表信息按期(每30秒)更新一次。每次返回註冊列表信息可能與Eureka Client的緩存信息不一樣,Eureka Client自動處理。
若是因爲某種緣由致使註冊信息列表信息不能及時匹配,Eureka Client則會從新獲取整個註冊表信息。Eureka Server緩存註冊列表信息,整個註冊表以及每一個應用程序的信息進行了壓縮,壓縮內容和沒有壓縮的內容徹底相同。Eureka Client和Eureka Server可使用JSON/XML格式進行通信。在默認狀況下Eureka Client使用壓縮JSON形式來獲取註冊列表的信息。
八、Remote Call:遠程調用
當Eureka Client從註冊中心獲取到服務提供者信息後,就能夠經過HTTP請求調用對應的服務;服務提供者有多個時,Eureka Client客戶端會自動經過Ribbon自動進行負載均衡。
3、自我保護機制
默認請款下,若是Eureka Server在90秒內沒有接收到某個微服務實例的心跳,會註銷該實例。可是在微服務架構下服務之間一般都是跨進程調用,網絡通訊每每面臨不少問題,好比微服務狀態正常,網絡分區故障,致使此實例被註銷。
固定時間內大量實例被註銷,可能會嚴重威脅某個微服務架構的可用性,爲了解決這個問題,Eureka開發了自我保護機制,那麼什麼是自我保護機制呢?
Eureka Server在運行期間會去統計心跳失敗比例在15分鐘以內是否低於85%,若是低於85%,Eureka Server即進入自我保護機制。
Eureka Server觸發自我保護機制後,頁面會出現提示:
Eureka Server進入自我保護機制,會出現如下幾種狀況:
(1)Eureka再也不從註冊列表中移除由於長時間沒收到心跳而應該過時的服務。
(2)Eureka仍然可以接受新服務的註冊和查詢,可是不會被同步到其它節點上(即保證當前節點依然可用)。
(3)當網絡穩定後,當前實例新的註冊信息會被同步到其它節點上。
Eureka自我保護機制是爲了防止誤殺服務而提供的一種機制。當個別客戶端出現心跳失聯時,則認爲是客戶端的問題,剔除客戶端;當Eureka 捕獲到大量的心跳失敗時,則認爲多是網絡問題,進入自我保護機制;當客戶端心跳恢復時,Eureka會自動退出自我保護機制。
若是在保護期內恰好這個服務提供者非正常下線了,此時服務消費者就會拿到一無效的服務實例,則會調用失敗。對於這個問題須要服務消費者要有一些容錯機制,好比重試,斷路器等。
4、Eureka高可用集羣
理論上來說,服務消費者本地緩存了服務提供者的地址,即便Eureka Server宕機,也不會影響服務之間的調用,可是一旦涉及到服務的上下線,本地的緩存信息將會出現誤差,影響整個微服務的穩定性,所以搭建Eureka Server集羣來提升整個架構的高可用性,是很是必要的。
從圖中能夠看出Eureka Server集羣相互之間經過Replicate來同步數據,相互之間不區分主節點和從節點,全部的節點都是平等的。在這種架構中,節點經過彼此互相註冊提升可用性,每一個節點須要添加一個或多個有效的serviceURL指向其餘節點。
若是某臺 Eureka Server 宕機,Eureka Client 的請求會自動切換到新的 Eureka Server 節點。當宕機的服務器從新恢復後,Eureka 會再次將其歸入到服務器集羣管理之中。當節點開始接受客戶端請求時,全部的操做都會進行節點間複製,將請求複製到其它 Eureka Server 當前所知的全部節點中。
另外 Eureka Server 的同步遵循着一個很是簡單的原則:只要有一條邊將節點鏈接,就能夠進行信息傳播與同步。因此,若是存在多個節點,只須要將節點之間兩兩鏈接起來造成通路,那麼其它註冊中心均可以共享信息。每一個 Eureka Server 同時也是 Eureka Client,多個 Eureka Server 之間經過 P2P 的方式完成服務註冊表的同步。
Eureka Server 集羣之間的狀態是採用異步方式同步的,因此不保證節點間的狀態必定是一致的,不過基本能保證最終狀態是一致的。
5、 Eureka分區
Eureka提供了Region和Zone兩個概念來進行分區:
Region:能夠理解爲地理上的不一樣區域,好比亞洲地區,中國地區,大連地區等等。沒有具體大小的限制。根據項目具體的狀況,能夠自行合理劃分Region。
Zone:能夠簡單理解爲region內的具體機房,好比說region劃分爲大連,大連有兩個機房,就能夠再次region之下劃分出zone1,zone2兩個zone。
6、Eureka保證AP
Eureka Server 各個節點都是平等的,幾個節點掛掉不會影響正常節點的工做,剩餘的節點依然能夠提供註冊和查詢服務。而 Eureka Client 在向某個 Eureka 註冊時,若是發現鏈接失敗,則會自動切換至其它節點。只要有一臺 Eureka Server 還在,就能保證註冊服務可用(保證可用性),只不過查到的信息可能不是最新的(不保證強一致性)。
7、Eureka工做流程
一、Eureka Server啓動成功,等待服務端註冊。
在啓動過程當中若是配置了集羣,集羣之間定時經過Replicate同步註冊表,每一個Eureka Server都存在獨立完整的服務註冊表信息。
二、Eureka Client啓動時根據配置的Eureka Server地址去註冊中心註冊服務。
三、Eureka Client會每30秒向Eureka Server發送一次心跳,證實客戶端服務正常。
四、當Eureka Server90秒內沒有收到Eureka Client的心跳,註冊中心則認爲該節點失效,會註銷該實例。
五、單位時間內Eureka Server統計到大量的Eureka Client沒有發送心跳,則認爲可能爲網絡異常,進入自我保護機制,再也不剔除沒有發送心跳的客戶端。
六、當Eureka Client心跳恢復正常後,Eureka Server自動退出自我保護機制。
七、Eureka Client定時全量或者增量從註冊中心獲取服務註冊表,而且將獲取到的信息緩存在本地。
八、服務調用時,Eureka Client會先從本地緩存找尋調取的服務。若是獲取不到,先從註冊中心刷新註冊表,再同步到本地緩存。
九、Eureka Client獲取到目標服務器信息,發起服務調用。
十、Eureka Client程序關閉時向Eureka Server發送取消請求,Eureka Server將實例從註冊表中剔除。
8、 Eureka Server數據存儲
Eureka Server的數據存儲分爲兩層:數據存儲層和緩存層。
數據存儲層記錄註冊到 Eureka Server上的服務信息,緩存層是通過包裝後的數據,能夠直接在 Eureka Client調用時返回。
Eureka Server的數據存儲層是雙層的ConcurrentHashMap,咱們知道 ConcurrentHashMap 是線程安全高效的Map集合。
private final ConcurrentHashMap<String, Map<String, Lease<InstanceInfo>>> registry= new ConcurrentHashMap<String, Map<String, Lease<InstanceInfo>>>();
第一層的ConcurrentHashMap的key=spring.application.name也就是客戶端實例註冊的應用名;value爲嵌套的ConcurrentHashMap。
第二層嵌套的ConcurrentHashMap的key=instanceId也就是服務的惟一實例id,value爲Lease對象,Lease對象存儲着這個實例的全部註冊信息,包括IP、端口、屬性等。
根據這個存儲結構咱們能夠發現,Eureka Server 第一層都是存儲着全部的服務名,以及服務名對應的實例信息,也就是說第一層都是按照服務應用名這個維度來切分存儲:
應用名1:應用1實例 Map
應該名2:應用2實例 Map
...
第二層是根據實例的惟一 ID 來存儲的,那麼按照這個結構最終的存儲數據格式爲:
: 應用1實例A:實例A的註冊信息
應用名1:應用1實例: 應用1實例B:實例B的註冊信息
: 應用1實例C:實例C的註冊信息 : ....
: 應用2實例F:實例F的註冊信息
應該名2:應用2實例: 應用2實例G:實例G的註冊信息
: ...
...
數據存儲層數據結構以下圖所示:
當如服務的狀態發生變動時,會同步 Eureka Server 中的 registry 數據信息,好比服務註冊、剔除服務時。
9、 Eureka的緩存機制
Eureka Server 爲了提供響應效率,提供了兩層的緩存結構,將 Eureka Client 所須要的註冊信息,直接存儲在緩存結構中。
第一層緩存:readOnlyCacheMap,本質上是 ConcurrentHashMap,依賴定時從 readWriteCacheMap 同步數據,默認時間爲 30 秒。
readOnlyCacheMap : 是一個 CurrentHashMap的只讀緩存,這個主要爲了供客戶端獲取註冊信息時使用,其緩存更新,依賴於定時器的更新,經過和 readWriteCacheMap 的值作對比,若是數據不一致,則以 readWriteCacheMap 的數據爲準。
第二層緩存: readWriteCacheMap ,本質上是Guava緩存。
readWriteCacheMap:readWriteCacheMap 的數據主要同步於存儲層。當獲取緩存時判斷緩存中是否沒有數據, 若是不存在此數據,則經過 CacheLoader 的 load 方法去加載,加載成功以後將數據放入緩存,同時返回數據。
readWriteCacheMap 緩存過時時間,默認爲 180 秒,當服務下線、過時、註冊、狀態變動,都會來清除此緩存中的數據。
Eureka Client 獲取全量或者增量的數據時,會先從一級緩存中獲取;若是一級緩存中不存在,再從二級緩存中獲取;若是二級緩存也不存在,這時候先將存儲層的數據同步到緩存中,再從緩存中獲取。
經過 Eureka Server 的二層緩存機制,能夠很是有效地提高 Eureka Server 的響應時間,經過數據存儲層和緩存層的數據切割,根據使用場景來提供不一樣的數據支持。
10、代碼實例
一、項目架構:
二、Eureka服務端application.yml
server:
port: 9000
eureka:
instance:
hostname: localhost
client:
register-with-eureka: false fetch-registry: false service-url: defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ instance: prefer-ip-address: true
三、客戶端啓動類
package cn.itcast.product;
...
@SpringBootApplication
@EntityScan("cn.itcast.product.entity")
@EnableEurekaClient
public class ProductServiceApplication {
public static void main(String[] args) {
SpringApplication.run(ProductServiceApplication.class, args);
}
}
四、一些基本的controller、service、bean就不寫了,使用的是spring data jpa方式查詢的數據庫。
五、啓動服務
Eureka Server --> Eureka Providor --> Eureka Consumer
Eureka Server
六、Eureka Consumer調用服務
11、總結
講解了 Eureka核心概念、 Eureka自我保護機制、 Eureka高可用集羣。經過分析 Eureka工做原理,能夠明顯地感覺到 Eureka設計之巧妙,經過一系列的機制,完美的解決了註冊中心的穩定性和高可用性。
Eureka 爲了保障註冊中心的高可用性,容忍了數據的非強一致性,服務節點的數據可能不一致, Eureka Client間的數據可能不一致。比較適合跨越多機房、對註冊中心服務可用性要求較高的使用場景