一祝懂、eureka概述
1、背景
(1)netflix公司與AWS的ELB
- netflix是世界上最大的流媒體視頻網站拘鞋,其公司的架構師基于AWS云開發(fā)的砚蓬。在AWS中使用的負載均衡器是ELB(Elastic Load Balancing),即彈性負載均衡通過流量分發(fā)擴展應用系統(tǒng)對外的服務能力(類似阿里云SLB服務)盆色。理論上是可以通過ELB對內部進行負載均衡的灰蛙,但是如果這樣就會暴露到外網,存在安全性問題隔躲;另外ELB是基于傳統(tǒng)的代理的負載均衡解決方案摩梧,無法直接基于服務元數據信息定義負載均衡算法。也就是說使用ELB有一定的限制宣旱,無法根據復雜的生產環(huán)境提供更為復雜的負載均衡方案仅父,且存在一定的安全隱患。
(2)eureka誕生
- netflix鑒于自己的生產環(huán)境,設計出了eureka笙纤,一方面給內部服務做服務發(fā)現耗溜,另一方面可以結合ribbon組件提供各種個性化的負載均衡算法。ELB亦是傳統(tǒng)的基于代理實現的負載均衡解決方案而Eureka則與之不同省容,Eureka屬于客戶端發(fā)現模式强霎,客戶端負責決定相應服務實例的網絡位置,并且對請求實現負載均衡蓉冈。客戶端從一個服務注冊服務中查詢所有可用服務實例的庫轩触,并緩存到本地寞酿。
(3)ELB和eureka搭配使用
-
在生產中如果是使用AWS等云服務,可以結合eureka一起使用(以AWS為例)脱柱,ELB用來對客戶端或者終端設備進行請求負載均衡伐弹,而eureka用來對中間層的服務做服務發(fā)現,配合其他組件提供負載均衡的能力榨为。
2惨好、eureka優(yōu)勢
(1)提供完成的服務注冊和服務發(fā)現實現
- 首先是提供了完整的服務注冊和服務發(fā)現實現,并且也經受住了Netflix自己的生產環(huán)境考驗随闺,相對使用起來會比較省心日川。
(2)與spirngcloud無縫集成
- 我們的項目本身就使用了Spring Cloud和Spring Boot,同時Spring Cloud還有一套非常完善的開源代碼來整合Eureka矩乐,所以使用起來非常方便龄句。另外,Eureka還支持在我們應用自身的容器中啟動散罕,也就是說我們的應用啟動完之后分歇,既充當了Eureka的角色,同時也是服務的提供者欧漱。這樣就極大的提高了服務的可用性
(3)采用AP而非CP
- eureka是在部署AWS的背景下面設計的职抡,其設計認為,在云端误甚,特別是大規(guī)模部署情況下面缚甩,失敗是不可以避免的,可能是因為eureka自身部署失敗或者網絡分區(qū)等情況導致服務不可用窑邦,這些問題是不可以避免的蹄胰,要解決這個問題就需要eureka在網絡分區(qū)的時候,還能夠正常提供服務奕翔,因此eureka選擇滿足availability這個特性裕寨。
在生產實踐中,服務注冊及發(fā)現中保留可用以及過期的數據總比丟失可用的數據好。---peter kelly
- eureka選擇了A也就必須放棄C宾袜,也就是說在eureka中采用最終一致性的方式來保證數據的一致性問題捻艳,因此實例的注冊信息在集群的所有節(jié)點之間的數據都不是強一性的,需要客戶端能支持負載均衡算法及失敗重試等機制庆猫。
(4)開源
- 代碼是開源的认轨,所以非常便于我們了解它的實現原理和排查問題。需要的話還可以在上面進行二次開發(fā)月培。
3嘁字、eureka和zk作為注冊中心比較
比較項目 | zk | eureka |
---|---|---|
設計原則 | CP | AP |
優(yōu)點 | 數據強一致 | 服務高可用 |
缺點 | 網絡分區(qū)會影響 Leader 選舉,超過閾值后集群不可用 | 服務節(jié)點間的數據可能不一致杉畜; Client-Server 間的數據可能不一致纪蜒; |
使用場景 | 單機房集群,對數據一致性要求較高 | 云機房集群此叠,跨越多機房部署纯续;對注冊中心服務可用性要求較高 |
二、eureka架構設計
1灭袁、設計理念
(1)AP由于CP
(2)Peer to Peer設計
- 一般而言在分布式系統(tǒng)的數據有多個副本之間的復制方式猬错,可以分為主從復制和對等復制
主從復制:Master-Slave模式,一個主副本和多個從副本茸歧,所有數據的寫操作都是提交到主副本倦炒,最后由主副本更新到其他的從副本(常采用異步更新),通常寫是整個系統(tǒng)的瓶頸所在软瞎。
對等復制:副本之間不分主從析校,任何的副本都可以接受寫數據,然后副本之間進行數據更新铜涉。在對等復制中智玻,由于每一個副本都可以進行寫操作,各個副本之間的數據同步及沖突處理是一個比較難解決的問題芙代。
- eureka中的對等復制機制
1吊奢、客戶端:在客戶端中配置相應的服務端的多個peer節(jié)點,在客戶端實際操作中有如下幾點規(guī)律纹烹;(1)有多個分區(qū)時候页滚,優(yōu)先選擇與應用實例所在分區(qū)一樣的其他服務實例,如果沒有的話選擇默認是defaultZone(2)客戶端會維護一個可用的server列表铺呵,請求的時候優(yōu)先從可用的列表中進行選擇裹驰,如果請求失敗切換到下一個server進行重試,重試次數為3次(3)為了防止客戶端請求服務端的節(jié)點不均勻現象片挂,客戶端有一個定時任務來刷新并隨機化eureka server的列表幻林。
2贞盯、服務端:server本身依賴于客戶端,也就是每一個server是作為其他server的客戶端存在沪饺。在一個server啟動的時候躏敢,有一個synvUp操作,通過客戶端請求其他的server節(jié)點中的一個節(jié)點獲取注冊的應用實例信息整葡,然后復制到其他的peer節(jié)點件余。eureka中采用版本號(lastDirtyTimestamp)和心跳機制(renewLease從新租約方式)的方式來解決數據復制過程中的沖突問題。
(3)Zone和region的設計
- 使用region來代表一個獨立的地理區(qū)域遭居,比如us-east-1啼器、us-east-2,、us-west-1等俱萍。在每一個region下面還分為多個AvailabilityZone端壳,一個region對應多個AvailabilityZone,不同的region之間相互隔離鼠次。默認情況下面資源只是在單個region之間的AvailabilityZone之間進行復制,跨region之間不會進行資源的復制芋齿。
- AvailabilityZone看成是region下面的一個一個機房腥寇,各個機房相對獨立,主要是為了region的高可用考慮的觅捆,一個region下面的機房掛了赦役,還有其他的機房可以使用。
- 一個AvailabilityZone可以設置多個server實例栅炒,他們之間構成peer節(jié)點掂摔,然后采用peer to peer的復制模式進行數據復制。
(4)self preservation設計
- 在分布式系統(tǒng)設計中赢赊,通常需要對應用實例的存活進行健康檢驗乙漓,這里比較難處理的就是網絡偶爾抖動或者短暫不可用而造成的誤判。因此eureka設計了self preservation機制释移。server和client之間有一個租約叭披,client定期發(fā)送心跳來維護這個租約,表示心跳還活著玩讳,eureka通過當前注冊的實例數量涩蜘,去計算每分鐘應用從應用實例接受到的心跳數量,如果近一分鐘接受到的租約的次數小于等于指定的閾值熏纯,則關閉租約失效剔除同诫,禁止定時任務剔除失效的實例,從而保護注冊信息樟澜。
2误窖、組件調用關系設計
(1)服務提供者
1叮盘、啟動后,向注冊中心發(fā)起 register 請求贩猎,注冊服務
2熊户、在運行過程中,定時向注冊中心發(fā)送 renew 心跳吭服,證明“我還活著”嚷堡。
3、停止服務提供者艇棕,向注冊中心發(fā)起 cancel 請求蝌戒,清空當前服務注冊信息。
(2)服務消費者
1沼琉、啟動后北苟,從注冊中心拉取服務注冊信息
2、在運行過程中打瘪,定時更新服務注冊信息友鼻。
3、服務消費者發(fā)起遠程調用:
a> 服務消費者(北京)會從服務注冊信息中選擇同機房的服務提供者(北京)闺骚,發(fā)起遠程調用彩扔。只有同機房的服務提供者掛了才會選擇其他機房的服務提供者(青島)。
b> 服務消費者(天津)因為同機房內沒有服務提供者僻爽,則會按負載均衡算法選擇北京或青島的服務提供者虫碉,發(fā)起遠程調用。
(3)服務注冊中心
1胸梆、啟動后敦捧,從其他節(jié)點拉取服務注冊信息。
2碰镜、運行過程中兢卵,定時運行 evict 任務,剔除沒有按時 renew 的服務(包括非正常停止和網絡故障的服務)绪颖。
3济蝉、運行過程中,接收到的 register菠发、renew王滤、cancel 請求,都會同步至其他注冊中心節(jié)點
3滓鸠、數據存儲結構
- Eureka 的數據存儲分了兩層:數據存儲層和緩存層雁乡。
Eureka Client 在拉取服務信息時,先從緩存層獲让铀住(相當于 Redis)踱稍,如果獲取不到曲饱,先把數據存儲層的數據加載到緩存中(相當于 Mysql),再從緩存中獲取珠月。值得注意的是扩淀,數據存儲層的數據結構是服務信息,而緩存中保存的是經過處理加工過的啤挎、可以直接傳輸到 Eureka Client 的數據結構驻谆。
(1)數據存儲層
第一層的 key 是spring.application.name,value 是第二層 ConcurrentHashMap庆聘;
第二層 ConcurrentHashMap 的 key 是服務的 InstanceId胜臊,value 是 Lease 對象;
Lease 對象包含了服務詳情和服務治理相關的屬性伙判。
- 更新一級緩存:
Eureka Server 內置了一個 TimerTask象对,定時將二級緩存中的數據同步到一級緩存(這個動作包括了刪除和加載)。
(2)二級緩存層
一級緩存:ConcurrentHashMap<Key,Value> readOnlyCacheMap宴抚,本質上是 HashMap勒魔,無過期時間,保存服務信息的對外輸出數據結構菇曲。
二級緩存:Loading<Key,Value> readWriteCacheMap冠绢,本質上是 guava 的緩存,包含失效機制羊娃,保存服務信息的對外輸出數據結構唐全。
-
二級緩存的更新機制:
- 刪除二級緩存:
1埃跷、Eureka Client 發(fā)送 register蕊玷、renew 和 cancel 請求并更新 registry 注冊表之后,刪除二級緩存弥雹;2垃帅、Eureka Server 自身的 Evict Task 剔除服務后,刪除二級緩存剪勿;3贸诚、二級緩存本身設置了 guava 的失效機制,隔一段時間后自己自動失效厕吉;
- 加載二級緩存:
1酱固、Eureka Client 發(fā)送 getRegistry 請求后,如果二級緩存中沒有头朱,就觸發(fā) guava 的 load运悲,即從 registry 中獲取原始服務信息后進行處理加工,再加載到二級緩存中项钮。
2班眯、Eureka Server 更新一級緩存的時候希停,如果二級緩存沒有數據,也會觸發(fā) guava 的 load署隘。
- 重點關注:ResponseCacheImpl類
三宠能、eureka高可用原理分析
- 前面講了eureka是基于AWS開發(fā)出來的框架,因此eureka天生的支持region和availabilityZone的概念磁餐。
1违崇、默認情況下面不同region是相互隔離的,region之間的數據是不會復制的崖媚,但是eureka client提供了fetch-remote-regions-registry配置亦歉,作用是拉取遠程的注冊信息到本地
2、availabilityZone畅哑,eureka中默認eureka-client-prefer-zone-eureka配置為true肴楷,也就是拉取serverUrl時候,默認選取和應用實例同一個zone的eureka server列表荠呐。
1赛蔫、客戶端高可用原理
(1)在client啟動之前,如果沒有eureka server泥张,則通過配置eureka.client.back-registry-impl從備份的registry讀取關鍵服務的信息呵恢。
(2)在client啟動后,如果運行時候server全部掛掉了媚创,本地內存有l(wèi)ocalRegion之前獲取的數據渗钉。
(3)如果是server部分掛了。如果預計恢復時間比較長钞钙,可以人工介入鳄橘,通過配置中心人工摘除服務(但是基本不用這樣做)。在client中會維護一份不可用的server列表芒炼,一旦心跳時候失敗瘫怜,當該列表的大小超過指定的閾值時候就會進行重新清空,重新清空后本刽,client會進行重試(默認3次)
2鲸湃、服務端高可用原理
- 服務端采用peer to peer的架構模式,原則上就是高可用的子寓。同時服務端還可以通過配置remoteRegionUrlsWithName來支持拉取遠程的region實例暗挑,如果當前的region掛了,會自動fallback到遠程的region獲取數據
- 同時服務端采用renew租約和定時心跳的方式保護注冊信息(self preservation機制)
參考:
微服務注冊中心 Eureka 架構深入解讀
重新定義springcloud
深度剖析服務發(fā)現組件Netflix Eureka
其他資料