【Spring Cloud系列】-Eureka服務(wù)端高可用詳解
上一篇《Eureka使用詳解》一文中我們?cè)敿?xì)介紹了什么是Spring Cloud微服務(wù)。Spring Cloud中Service注冊(cè)中心及其Client如何實(shí)現(xiàn)并如何完成服務(wù)注冊(cè)的。這一篇我們將介紹Eureka注冊(cè)中心的高可用如何實(shí)現(xiàn)及其使用中的注意事項(xiàng)。
一. 序言
微服務(wù)就是開發(fā)一組小型服務(wù)的方式來(lái)完成對(duì)系統(tǒng)整個(gè)開發(fā)。其中每個(gè)小微服務(wù)都獨(dú)立運(yùn)行在自己的進(jìn)程中,這些服務(wù)是圍繞業(yè)務(wù)功能構(gòu)建一個(gè)小微服務(wù)集群。其最終的目的就是:高容錯(cuò)、可擴(kuò)展、易部署。但當(dāng)我們?cè)贓ureka只采用單臺(tái)注冊(cè)服務(wù)中心時(shí),如果注冊(cè)中心服務(wù)崩潰,就會(huì)造成整個(gè)服務(wù)癱瘓。為解決這種風(fēng)險(xiǎn)。Eureka提供高可用的技術(shù)方案,下面將具體演示如果實(shí)現(xiàn)Eureka注冊(cè)中心的高可用。
二. 什么是高可用性
高可用(High Availability)指通過(guò)盡量縮短因日常維護(hù)操作和突發(fā)的系統(tǒng)崩潰所導(dǎo)致的停機(jī)時(shí)間,以提高系統(tǒng)和應(yīng)用的可用性。這也是和不間斷操作的容錯(cuò)技術(shù)不同。高可用是為了防止核心計(jì)算機(jī)應(yīng)用系統(tǒng)因故障突然停機(jī)的一種可靠的手段。
三. 什么是CAP
CAP原則又稱CAP定理,指的是一個(gè)分布式中,一致性(Consistency)、可用性(Availability)、分區(qū)容錯(cuò)(Partition-tolerance).一般在一個(gè)分布式系統(tǒng)中三個(gè)要素不可同是具有,只能選擇其中兩個(gè),具體如圖
-
一致性(Consistency)
在分布式系統(tǒng)中,所有節(jié)點(diǎn)在同一時(shí)刻的數(shù)據(jù)都是一致的。
-
可用性(Availability)
在集群中一部分節(jié)點(diǎn)故障后,集群整體是否還能響應(yīng)客戶端的讀寫請(qǐng)求。即每個(gè)請(qǐng)求不管成功與否都能得到響應(yīng)。
-
分區(qū)容錯(cuò)(Partition-tolerance)
保證系統(tǒng)中任意信息的丟失都不會(huì)影響系統(tǒng)的運(yùn)行。
一個(gè)分布式系統(tǒng)里面,節(jié)點(diǎn)組成的網(wǎng)絡(luò)本來(lái)應(yīng)該是連通。然而可能因?yàn)橐恍┕收?,使得有些?jié)點(diǎn)之間不連通,整個(gè)網(wǎng)絡(luò)就分成了幾塊區(qū)域。數(shù)據(jù)就散布在了這些不連通的區(qū)域中。這就叫分區(qū)。
-
AP
保持可用性和分區(qū)容錯(cuò)。如果選擇分區(qū)容錯(cuò)性和可用性,當(dāng)節(jié)點(diǎn)損壞時(shí),遇到分區(qū)事件,受影響的服務(wù)不需要等待數(shù)據(jù)一致,就可以對(duì)外提供服務(wù),保證了可用性就必須放棄一致性。
-
CP
保證一致性和分區(qū)容錯(cuò)。如果選擇分區(qū)容錯(cuò)性和一致性,為保證一致性,各個(gè)節(jié)點(diǎn)之間的數(shù)據(jù)必須保持一致,當(dāng)出現(xiàn)分區(qū)時(shí),會(huì)導(dǎo)致同步時(shí)間無(wú)限延長(zhǎng),在同步的這段時(shí)間就無(wú)法對(duì)外提供服務(wù),就無(wú)法保證可用性。
-
CA
保持一致性的同時(shí)保證可用性,這在分布式系統(tǒng)中是不存在的,因?yàn)榉謪^(qū)問題總是會(huì)出現(xiàn)在分布式系統(tǒng)中。出現(xiàn)分區(qū)就必然會(huì)產(chǎn)生一致性問題和可用性問題,一致性和可用性兩者只能選其一。
四. Eureka集群部署原理
- 原理
- Eureka Client內(nèi)置一個(gè) 使用輪詢負(fù)載算法的負(fù)載均衡器。服務(wù)啟動(dòng)后,Eureka Client將會(huì)向Eureka Server發(fā)送心跳更新服務(wù),如果Eureka Server在多個(gè)心跳周期內(nèi)沒有接收到某個(gè)服務(wù)的心跳,Eureka Server將會(huì)從服務(wù)注冊(cè)表中把這個(gè)服務(wù)節(jié)點(diǎn)移除(默認(rèn)90秒)。
- Eureka Server是基于netflix設(shè)計(jì)出來(lái)的,其服務(wù)注冊(cè)表中將會(huì)存儲(chǔ)所有可用服務(wù)節(jié)點(diǎn)的信息,支持region和availabilityZone的概念,采用peer to peer的架構(gòu)模式,也可以通過(guò)配置remoteRegionUrlsWithName來(lái)支持拉取遠(yuǎn)程的region實(shí)例,如果當(dāng)前的region掛了,會(huì)自動(dòng)fallback到遠(yuǎn)程的region獲取數(shù)據(jù),同時(shí)服務(wù)端采用renew租約和定時(shí)心跳的方式保護(hù)注冊(cè)信息(self preservation機(jī)制)。
四、Eureka集群部署案例實(shí)現(xiàn)
-
Eureka單機(jī)服務(wù)部署已在【Spring Cloud系列】- Eureka知識(shí)詳解中講解如何使用,在這基礎(chǔ)上我們構(gòu)建另外兩個(gè)服務(wù):Server-node-01、Server-node-02
-
更新配置文件(application.yml)
- eureka.client.register-with-eureka :表示是否將自己注冊(cè)到Eureka Server,默認(rèn)為true。
-
eureka.client.fetch-registry
:表示是否從Eureka Server獲取注冊(cè)信息,默認(rèn)為true -
eureka.client.serviceUrl.defaultZone
:設(shè)置與Eureka Server交互的地址,查詢服務(wù)和注冊(cè)服務(wù)都需要依賴這個(gè)地址。默認(rèn)是http://localhost:30000/eureka ;多個(gè)地址可使用 , 分隔。
-
Server-node-01配置文件
-
Server-node-02配置文件
-
更新Hosts文件
、
-
更新eureka-client配置
在生產(chǎn)中我們可能需要三臺(tái)或者大于三臺(tái)的注冊(cè)中心來(lái)保證服務(wù)的穩(wěn)定性,配置的原理其實(shí)都一樣,將注冊(cè)中心分別指向其它的注冊(cè)中心。這里只介紹三臺(tái)集群的配置情況,其實(shí)和雙節(jié)點(diǎn)的注冊(cè)中心類似,每臺(tái)注冊(cè)中心分別又指向其它兩個(gè)節(jié)點(diǎn)即可,使用application.yml來(lái)配置。
-
啟動(dòng)eureka-client服務(wù)輪詢注冊(cè)到服務(wù)端配置
五、Eureka集群測(cè)試效果
-
Serve-30000服務(wù)
-
Serve-30001服務(wù)
-
Serve-30002服務(wù)
六、Eureka 的數(shù)據(jù)同步方式
6.1. 復(fù)制方式
分布式系統(tǒng)的數(shù)據(jù)在多個(gè)副本之間的復(fù)制方式,主要有主從復(fù)制和對(duì)等復(fù)制
-
主從復(fù)制
就是 Master-Slave 模式,有一個(gè)主副本,其他為從副本,所有寫操作都提交到主副本,再由主副本更新到其他從副本。
寫壓力都集中在主副本上,是系統(tǒng)的瓶頸,從副本可以分擔(dān)讀請(qǐng)求。
-
對(duì)等復(fù)制
就是 Peer to Peer 模式,副本間不分主從,任何副本都可以接收寫操作,然后每個(gè)副本間互相進(jìn)行數(shù)據(jù)更新。
對(duì)等復(fù)制模式,任何副本都可以接收寫請(qǐng)求,不存在寫壓力瓶頸,但各個(gè)副本間數(shù)據(jù)同步時(shí)可能產(chǎn)生數(shù)據(jù)沖突。
Eureka 采用的就是 Peer to Peer 模式
6.2. 同步過(guò)程
Eureka Server 本身依賴了 Eureka Client,也就是每個(gè) Eureka Server 是作為其他 Eureka Server 的 Client。
Eureka Server 啟動(dòng)后,會(huì)通過(guò) Eureka Client 請(qǐng)求其他 Eureka Server 節(jié)點(diǎn)中的一個(gè)節(jié)點(diǎn),獲取注冊(cè)的服務(wù)信息,然后復(fù)制到其他 peer 節(jié)點(diǎn)。
Eureka Server 每當(dāng)自己的信息變更后,例如 Client 向自己發(fā)起注冊(cè)、續(xù)約、注銷請(qǐng)求, 就會(huì)把自己的最新信息通知給其他 Eureka Server,保持?jǐn)?shù)據(jù)同步。
如果自己的信息變更是另一個(gè)Eureka Server同步過(guò)來(lái)的,這是再同步回去的話就出現(xiàn)數(shù)據(jù)同步死循環(huán)了。
Eureka Server 在執(zhí)行復(fù)制操作的時(shí)候,使用 HEADER_REPLICATION
這個(gè) http header 來(lái)區(qū)分普通應(yīng)用實(shí)例的正常請(qǐng)求,說(shuō)明這是一個(gè)復(fù)制請(qǐng)求,這樣其他 peer 節(jié)點(diǎn)收到請(qǐng)求時(shí),就不會(huì)再對(duì)其進(jìn)行復(fù)制操作,從而避免死循環(huán)。
還有一個(gè)問題,就是數(shù)據(jù)沖突,比如 server A 向 server B 發(fā)起同步請(qǐng)求,如果 A 的數(shù)據(jù)比 B 的還舊,B 不可能接受 A 的數(shù)據(jù),那么 B 是如何知道 A 的數(shù)據(jù)是舊的呢?這時(shí) A 又應(yīng)該怎么辦呢?
數(shù)據(jù)的新舊一般是通過(guò)版本號(hào)來(lái)定義的,Eureka 是通過(guò) lastDirtyTimestamp 這個(gè)類似版本號(hào)的屬性來(lái)實(shí)現(xiàn)【lastDirtyTimestamp是注冊(cè)中心里面服務(wù)實(shí)例的一個(gè)屬性,表示此服務(wù)實(shí)例最近一次變更時(shí)間】
比如 Eureka Server A 向 Eureka Server B 復(fù)制數(shù)據(jù),數(shù)據(jù)沖突有2種情況:
- A 的數(shù)據(jù)比 B 的新,B 返回 404,A 重新把這個(gè)應(yīng)用實(shí)例注冊(cè)到 B。
- A 的數(shù)據(jù)比 B 的舊,B 返回 409,要求 A 同步 B 的數(shù)據(jù)。
還有一個(gè)重要的機(jī)制:hearbeat 心跳,即續(xù)約操作,來(lái)進(jìn)行數(shù)據(jù)的最終修復(fù),因?yàn)楣?jié)點(diǎn)間的復(fù)制可能會(huì)出錯(cuò),通過(guò)心跳就可以發(fā)現(xiàn)錯(cuò)誤,進(jìn)行彌補(bǔ)。
七、Eureka中元數(shù)據(jù)
Eureka的元數(shù)據(jù)有兩種:標(biāo)準(zhǔn)元數(shù)據(jù)和自定義元數(shù)據(jù)
-
標(biāo)準(zhǔn)元數(shù)據(jù)
主機(jī)名、IP地址、端口號(hào)、狀態(tài)頁(yè)和健康檢查等信息,這些信息都會(huì)被發(fā)布在服務(wù)注冊(cè)表中,用于服務(wù)之間的調(diào)用。
-
自定義元數(shù)據(jù)
可以使用eureka.instance.metadata-map配置,這些元數(shù)據(jù)可以在遠(yuǎn)程客戶端中訪問,但是一般不改變客戶端行為,除非客戶端知道該元數(shù)據(jù)的含義
元數(shù)據(jù)在程序中的應(yīng)用
-
application中配置
eureka: instance: #標(biāo)準(zhǔn)元數(shù)據(jù) preferIpAddress: true ipAddress: 127.0.0.1 #自定義元數(shù)據(jù)信息 metadata-map: name-serve:goyeer-serve serve-code: v202306
-
程序代碼獲取Eureka配置的元數(shù)據(jù)
@Autowired DiscoveryClient discoveryClient; @RequestMapping("testDiscovery") public String testDiscovery() { List<ServiceInstance> serviceInstanceList = discoveryClient.getInstances("cloud-provider"); // 獲取第一個(gè)微服務(wù)實(shí)例的元數(shù)據(jù)信息 ServiceInstance serviceInstance = serviceInstanceList.get(0); //打印微服務(wù)實(shí)例的元數(shù)據(jù)信息 System.out.println(serviceInstance); return "testDiscovery"; }
八、Eureka自我保護(hù)
-
什么是自我保護(hù)
服務(wù)提供者會(huì)定期的向注冊(cè)中心通信續(xù)約自己;如服務(wù)提供者和注冊(cè)中心之間的網(wǎng)絡(luò)有點(diǎn)問題,不代表服務(wù)提供者不可用,不代表服務(wù)消費(fèi)者無(wú)法訪問服務(wù)提供者;如果在15分鐘內(nèi)超過(guò)85%的客戶端節(jié)點(diǎn)都沒有正常的心跳,那么Eureka就認(rèn)為客戶端與注冊(cè)中心出現(xiàn)了網(wǎng)絡(luò)故障,Eureka Server自動(dòng)進(jìn)入自我保護(hù)機(jī)制。
-
為什么會(huì)有自我保護(hù)機(jī)制
默認(rèn)情況下,如果Eureka Server在一定時(shí)間內(nèi)(默認(rèn)90秒)沒有接收到某個(gè)微服務(wù)實(shí)例的心跳, Eureka Server將會(huì)移除該實(shí)例。但是當(dāng)網(wǎng)絡(luò)分區(qū)故障發(fā)生時(shí),微服務(wù)與Eureka Server之間無(wú)法正常通 信,而微服務(wù)本身是正常運(yùn)行的,此時(shí)不應(yīng)該移除這個(gè)微服務(wù),所以引入了自我保護(hù)機(jī)制。
當(dāng)處于自我保護(hù)模式時(shí):
-
不會(huì)剔除任何服務(wù)實(shí)例(可能是服務(wù)提供者和EurekaServer之間網(wǎng)絡(luò)問題),保證了大多數(shù)服務(wù)依 然可用;
-
Eureka Server仍然能夠接受新服務(wù)的注冊(cè)和查詢請(qǐng)求,但是不會(huì)被同步到其它節(jié)點(diǎn)上,保證當(dāng)前節(jié)點(diǎn)依然可用,當(dāng)網(wǎng)絡(luò)穩(wěn)定時(shí),當(dāng)前Eureka Server新的注冊(cè)信息會(huì)被同步到其它節(jié)點(diǎn)中;
-
在Eureka Server工程中通過(guò)eureka.server.enable-self-preservation配置可用關(guān)停自我保護(hù),默認(rèn)值是打開的
eureka: server: #是否開啟自我保護(hù),生產(chǎn)環(huán)境建議開啟,默認(rèn)開啟 enableSelfPreservation: true
經(jīng)驗(yàn):建議生產(chǎn)環(huán)境打開自我保護(hù)機(jī)制
-
九、Eureka中常用注解
-
@EnableEurekaClient與@EnableDiscoveryClient
-
相同點(diǎn)
@EnableDiscoveryClient
和
@EnableEurekaClient 共同點(diǎn)就是:都是能夠讓注冊(cè)中心能夠發(fā)現(xiàn),掃描到改服務(wù); -
不同點(diǎn)
@EnableEurekaClient只適用于Eureka作為注冊(cè)中心
@EnableDiscoveryClient可以是其他注冊(cè)中心如Zookeeper
-
-
@EnableEurekaServer
開啟 eureka server 服務(wù)端,可以接受其他服務(wù)注冊(cè)進(jìn)來(lái)
十、Eureka總結(jié)
-
AP: 非強(qiáng)一致, 要求客戶端支持負(fù)載均衡及失敗重試
-
對(duì)等復(fù)制:每個(gè)節(jié)點(diǎn)都接受寫操作, 節(jié)點(diǎn)之間相互同步數(shù)據(jù),當(dāng)數(shù)據(jù)沖突時(shí),通過(guò)比較節(jié)點(diǎn)數(shù)據(jù)的版本號(hào) lastDirtyTimestamp 來(lái)同步最新的數(shù)據(jù)
-
Zone, Region :默認(rèn)數(shù)據(jù)同步只會(huì)發(fā)生在 Region 下面的多個(gè) Zone 之間, 跨 Region 不會(huì)同步
-
self preservation:eureka server 收不到服務(wù)心跳有兩種情況:
一種是個(gè)別服務(wù)掛了,就走服務(wù)續(xù)約失效剔除的機(jī)制;如果 Eureka Server 默認(rèn)90秒沒有接收到某個(gè)微服務(wù)實(shí)例的心跳,Eureka Server 將會(huì)剔除該實(shí)例。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-490054.html
另一種情況就是微服務(wù)實(shí)例正常,但由于網(wǎng)絡(luò)分區(qū)故障沒收到心跳,這種情況就不應(yīng)該剔除服務(wù),所以就有了自我保護(hù)機(jī)制,如果在 15 分鐘內(nèi)超過(guò) 85% 的客戶端節(jié)點(diǎn)都沒有正常的心跳,Eureka Server 自動(dòng)進(jìn)入自我保護(hù)機(jī)制, 就會(huì)關(guān)閉服務(wù)續(xù)約失效剔除的機(jī)制文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-490054.html
到了這里,關(guān)于【Spring Cloud系列】-Eureka服務(wù)端高可用詳解的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!