您好,登錄后才能下訂單哦!
這篇文章主要講解了“什么是Eureka”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“什么是Eureka”吧!
什么是服務(wù)注冊(cè)?
首先我們來了解下,服務(wù)注冊(cè)、服務(wù)發(fā)現(xiàn)和服務(wù)注冊(cè)中心的之間的關(guān)系。
舉個(gè)形象的例子,三者之間的關(guān)系就好像是供貨商,顧客和商店。
首先各地的供貨商會(huì)將各種商品提供給商店,然后顧客需要商品的時(shí)候會(huì)去商店購買。
注冊(cè)中心就好比是這個(gè)商店,供貨商的動(dòng)作就是服務(wù)注冊(cè),商品就是注冊(cè)的服務(wù)。
當(dāng)部署的服務(wù)啟動(dòng)后,會(huì)注冊(cè)到注冊(cè)中心,消費(fèi)者需要什么樣的服務(wù),就自己去注冊(cè)中心拉取。
那么到底什么是服務(wù)注冊(cè),為什么要將服務(wù)注冊(cè)到注冊(cè)中心呢?
服務(wù)注冊(cè)指的是服務(wù)在啟動(dòng)時(shí)將服務(wù)的信息注冊(cè)到注冊(cè)中心中,由注冊(cè)中心統(tǒng)一對(duì)所有的注冊(cè)的服務(wù)進(jìn)行管理。
現(xiàn)在我們想想,假如你是消費(fèi)者,你需要買一個(gè)商品,你可以去商店,也可以直接去供貨商。
但是如果今天你要買很多商品,而且我們并不知道每個(gè)商品對(duì)應(yīng)的供應(yīng)商的地址,那么你就得挨家挨戶的去跑供貨商購買商品。
是不是就很麻煩了,倘若此時(shí)有一家商店,匯總了多家供貨商的商品,那你是不是只需要去這一家商店就能購買到你需要的所有的商品了呢?
這樣是不是就方便了。
在我們現(xiàn)實(shí)開發(fā)中,比如我們需要獲取用戶信息的時(shí)候,而此時(shí),我們的用戶服務(wù)只部署了一個(gè)節(jié)點(diǎn),那我們就可以使用IP+端口的形式訪問服務(wù)。
當(dāng)此時(shí)我們的服務(wù)部署了10個(gè)節(jié)點(diǎn)后,我們可以通過域名訪問,通過nginx轉(zhuǎn)發(fā)到某一個(gè)節(jié)點(diǎn)上,訪問該節(jié)點(diǎn)的服務(wù)。
使用過nginx的小伙伴們都知道,每當(dāng)我們需要新增一個(gè)節(jié)點(diǎn)的時(shí)候,我們就需要去修改nginx的配置文件,一旦服務(wù)部署的節(jié)點(diǎn)過多,頻繁修改配置文件就變成了一件極其麻煩的事情。
這個(gè)時(shí)候,我們的注冊(cè)中心,就應(yīng)該粉墨登場(chǎng)了。
注冊(cè)中心一登場(chǎng),我們就盡管部署服務(wù)節(jié)點(diǎn),部署完成后,服務(wù)啟動(dòng),服務(wù)的信息就會(huì)被注冊(cè)到注冊(cè)中心,我們就不需要擔(dān)心是不是又要去修改配置文件了。
什么是服務(wù)發(fā)現(xiàn)?
服務(wù)發(fā)現(xiàn)有兩種模式:一種是客戶端發(fā)現(xiàn)模式,一種是服務(wù)端發(fā)現(xiàn)模式。Eureka采用的是客戶端發(fā)現(xiàn)模式。
客戶端發(fā)現(xiàn)模式就好比我是一個(gè)土豪顧客,我去了商店,我把所有的商品都買回家,需要的時(shí)候在這些商品里面尋找。
因?yàn)槲沂峭梁?,所以我?dāng)然不能忍受商店里有新品上架,而我卻沒有,所以我每隔一段時(shí)間就會(huì)商店增量獲取最新的商品。
這就是Eureka中的Fetch Registry,抓取注冊(cè)信息。
Eureka Client 從 Eureka Server 獲取注冊(cè)表信息并在本地緩存。
這里我們注意一下,Eureka Client并不是直接去服務(wù)注冊(cè)表中獲取數(shù)據(jù),而是從ReadOnly緩存中獲取數(shù)據(jù)。
并且會(huì)通過在上一個(gè)獲取周期和當(dāng)前獲取周期之間獲取增量更新,這些信息會(huì)定期更新(每30秒更新一次)。
獲取的時(shí)候可能返回相同的實(shí)例。Eureka Client會(huì)自動(dòng)處理重復(fù)信息。
因?yàn)槲业耐梁佬袨?,我已?jīng)被商店老板記錄在它的VVIP名單上了??上煊胁粶y(cè)風(fēng)云,我破產(chǎn)了,我再也不能這么土豪了,沒辦法,我告訴了老板我破產(chǎn)了,老板聽了我的話,想都沒想,直接從他的VVIP名單上將我的名字給剔除了,社會(huì)就是這么現(xiàn)實(shí)。
這就是Eureka中的Cancel,取消。
每一個(gè)微服務(wù)節(jié)點(diǎn)關(guān)閉時(shí),Eureka Client會(huì)向Eureka Server發(fā)送一個(gè)取消請(qǐng)求。
Eureka Server收到你的取消請(qǐng)求后,就會(huì)將你從服務(wù)注冊(cè)表中給剔除。
商店老板是個(gè)傲嬌的人,她制定了一個(gè)規(guī)則,如果你是她VVIP名單上的人,你必須每隔一段時(shí)間就要去商店采購商品。
一旦你在一段時(shí)間內(nèi)沒有來采購,她就覺得你已經(jīng)沒有購買能力,不適合在她的VVIP名單上存在了。
她就會(huì)狠心的將你從她的VVIP名單上將我的名字給剔除了。
這就是Eureka中的Renew(更新 / 續(xù)借)
Eureka Client 內(nèi)部具備一個(gè)內(nèi)置的負(fù)載均衡器,它使用輪訓(xùn)(round-robin)負(fù)載算法。
在服務(wù)啟動(dòng)后,每隔一定周期(默認(rèn)30秒)向Eureka Server發(fā)送心跳。
如果Eureka Server在多個(gè)心跳周期內(nèi)(默認(rèn)90秒)沒有收到Eureka Client發(fā)送過來的心跳,Eureka Server將會(huì)在服務(wù)注冊(cè)表中將該節(jié)點(diǎn)剔除。
當(dāng)然了,服務(wù)發(fā)現(xiàn)去注冊(cè)中心拉取的是服務(wù)的信息,然后需要從服務(wù)信息中獲取到服務(wù)部署的節(jié)點(diǎn)信息,然后通過域名地址訪問到該節(jié)點(diǎn)的服務(wù)。
就好像一家商店,因?yàn)榭臻g太小,只是存放了一些商品的微縮模型,模型上寫著該商品所屬的供貨商地址,我們?nèi)ド痰昴玫皆撃P秃?,看到供貨商的地址,然后我們就可以直接去供貨商那兒直接購買商品了。
什么是注冊(cè)中心,注冊(cè)中心的作用?
注冊(cè)中心就是一個(gè)管理器,各個(gè)服務(wù)提供者將服務(wù)注冊(cè)到注冊(cè)中心,有注冊(cè)中心進(jìn)行統(tǒng)一的存儲(chǔ)和管理。
注冊(cè)中心同時(shí)還有著判斷服務(wù)是否可用,對(duì)于不可用的服務(wù)進(jìn)行剔除的功能。
至于如何判斷服務(wù)的可用性和如何剔除不可用的服務(wù),后續(xù)會(huì)有詳細(xì)的講解。
什么是 Eureka,有什么作用?
Eureka采用CS架構(gòu),它分為兩大組件。
一個(gè)是Eureka Server,注冊(cè)中心服務(wù)端。
當(dāng)各個(gè)微服務(wù)節(jié)點(diǎn)啟動(dòng)后,Eureka Server 會(huì)存儲(chǔ)服務(wù)提供者注冊(cè)上來的服務(wù)信息,并且提供二層緩存機(jī)制來維護(hù)整個(gè)注冊(cè)中心。
另一個(gè)是Eureka Client,注冊(cè)中心客戶端。
Eureka Client是一個(gè)java客戶端,它用來簡化和Eureka Server交互。
Eureka Client 會(huì)拉取、更新和緩存 Eureka Server 中的信息。
因此當(dāng)所有的 Eureka Server 節(jié)點(diǎn)都宕掉,服務(wù)消費(fèi)者依然可以使用緩存中的信息找到服務(wù)提供者,但是當(dāng)服務(wù)有更改的時(shí)候會(huì)出現(xiàn)信息不一致。
Eureka 架構(gòu)詳解
如下圖所示,這是官網(wǎng)提供給我們的Eureka的架構(gòu)圖Eureka 的架構(gòu),主要分為 Eureka Server 和 Eureka Client 兩部分,Eureka Client 又分為 Applicaton Service 和 Application Client,Applicaton Service 就是服務(wù)提供者,Application Client 就是服務(wù)消費(fèi)者。
我們首先會(huì)在應(yīng)用程序中依賴 Eureka Client,項(xiàng)目啟動(dòng)后 Eureka Client 會(huì)向 Eureka Server 發(fā)送請(qǐng)求,進(jìn)行注冊(cè),并將自己的一些信息發(fā)送給 Eureka Server。
注冊(cè)成功后,每隔一定的時(shí)間,Eureka Client 會(huì)向 Eureka Server 發(fā)送心跳來續(xù)約服務(wù),也就是匯報(bào)健康狀態(tài)。如果客戶端長時(shí)間沒有續(xù)約,那么 Eureka Server 大約將在 90 秒內(nèi)從服務(wù)器注冊(cè)表中刪除客戶端的信息。
Eureka Client 還會(huì)定期從 Eureka Server 拉取注冊(cè)表信息,然后根據(jù)負(fù)載均衡算法得到一個(gè)目標(biāo),并發(fā)起遠(yuǎn)程調(diào)用,關(guān)于負(fù)載均衡在后面的課時(shí)會(huì)詳細(xì)介紹,也就是 Ribbon 組件。
應(yīng)用停止時(shí)也會(huì)通知 Eureka Server 移除相關(guān)信息,信息成功移除后,對(duì)應(yīng)的客戶端會(huì)更新服務(wù)的信息,這樣就不會(huì)調(diào)用已經(jīng)下線的服務(wù)了,當(dāng)然這個(gè)會(huì)有延遲,有可能會(huì)調(diào)用到已經(jīng)失效的服務(wù),所以在客戶端會(huì)開啟失敗重試功能來避免這個(gè)問題。
Eureka Server 會(huì)有多個(gè)節(jié)點(diǎn)組成一個(gè)集群,保證高可用。Eureka Server 沒有集成其他第三方存儲(chǔ),而是存儲(chǔ)在內(nèi)存中。
所以 Eureka Server 之間會(huì)將注冊(cè)信息復(fù)制到集群中的 Eureka Server 的所有節(jié)點(diǎn)。
這樣數(shù)據(jù)才是共享狀態(tài),任何的 Eureka Client 都可以在任何一個(gè) Eureka Server 節(jié)點(diǎn)查找注冊(cè)表信息。
Eureka 的工作流程
Eureka 的自我保護(hù)機(jī)制
什么是自我保護(hù)機(jī)制
官方定義:自我保護(hù)模式正是一種針對(duì)網(wǎng)絡(luò)異常波動(dòng)時(shí)的安全保護(hù)措施,使用自我保護(hù)模式能使Eureka集群更加健壯穩(wěn)定的運(yùn)行。
為什么要開啟自我保護(hù)機(jī)制?
如果Eureka Server在一定時(shí)間內(nèi)(默認(rèn)90s)(可優(yōu)化)沒有收到某一個(gè)服務(wù)節(jié)點(diǎn)的心跳,Eureka Server將會(huì)移除該服務(wù)實(shí)例。
但是在某些時(shí)候,遇到網(wǎng)絡(luò)分區(qū)故障,服務(wù)節(jié)點(diǎn)實(shí)際上是正常存貨狀態(tài),但是卻無法和Eureka Server正常通信,此時(shí)如果沒有引入自我保護(hù)機(jī)制,Eureka Server就會(huì)將該服務(wù)節(jié)點(diǎn)剔除。
自我保護(hù)模式的工作機(jī)制
如果15分鐘內(nèi)超過85%的客戶端節(jié)點(diǎn)都沒有正常的心跳,那么Eureka Server就會(huì)認(rèn)為客戶端與注冊(cè)中心發(fā)生了網(wǎng)絡(luò)故障,Eureka Server進(jìn)入自我保護(hù)機(jī)制。
自我保護(hù)機(jī)制的缺點(diǎn)
如果在自我保護(hù)機(jī)制中,剛好某些服務(wù)節(jié)點(diǎn)非正常下線,但是Eureka Server并不會(huì)剔除該服務(wù)節(jié)點(diǎn),服務(wù)消費(fèi)者就會(huì)獲取到一個(gè)無效的服務(wù)實(shí)例。
解決方案
① :關(guān)閉自我保護(hù)機(jī)制(不推薦)
② :切換請(qǐng)求或斷路器,使用負(fù)載均衡的方式,設(shè)置當(dāng)一個(gè)請(qǐng)求超過多少秒還未得到響應(yīng),速度切換請(qǐng)求到下一個(gè)注冊(cè)服務(wù),例如使用Ribbon+Hystrix配置負(fù)載均衡和斷路器。
Eureka Server 進(jìn)入自我保護(hù)機(jī)制后
1、Eureka Server不在從注冊(cè)表中剔除因?yàn)殚L時(shí)間沒有和注冊(cè)中心續(xù)約的服務(wù)節(jié)點(diǎn)
2、Eureka Server仍然能夠接受新服務(wù)的注冊(cè)和查詢請(qǐng)求,但是不會(huì)同步到其他Eureka Server節(jié)點(diǎn)上
3、網(wǎng)絡(luò)正常后,當(dāng)前Eureka Server節(jié)點(diǎn)會(huì)將新的服務(wù)節(jié)點(diǎn)信息同步到其他Eureka Server節(jié)點(diǎn)上
如何開啟自我保護(hù)
通過eureka.server.enable-self-preservation=true/false來開啟或關(guān)閉自我保護(hù)機(jī)制。
其他關(guān)鍵配置:
清理失效服務(wù)節(jié)點(diǎn)的時(shí)間間隔:eureka.server.evication-interval-timer-in-ms默認(rèn)60s
續(xù)約間隔時(shí)間:eureka.instance.lease-renewal-interval-in-seconds默認(rèn)30s
續(xù)約到期時(shí)間:eureka.instance.lease-expiration-duration-in-seconds默認(rèn)90s
通過源碼窺探Eureka是如何開啟自我保護(hù)機(jī)制的
第一步,我們引入Eureka Server 依賴。
第二步,我們找到eureka-core jar包下的路徑為com.netflix.eureka下的registry包
第三步,進(jìn)入AbstractInstanceRegistry 類,找到evict方法,這個(gè)是定期剔除任務(wù)的線程最終執(zhí)行的方法
public void evict(long additionalLeaseMs) { logger.debug("Running the evict task"); //判斷自動(dòng)保護(hù)是否開啟,如果開啟了自動(dòng)保護(hù), //那么剔除服務(wù)的操作就不往下執(zhí)行,就不會(huì)剔除服務(wù)了 if (!this.isLeaseExpirationEnabled()) { logger.debug("DS: lease expiration is currently disabled."); } else { ... } }
第四步,我們找到isLeaseExpirationEnabled()方法的實(shí)現(xiàn)
public boolean isLeaseExpirationEnabled() { //首先判斷是否在配置文件中關(guān)閉了自我保護(hù),如果關(guān)閉了自我保護(hù)直接返回true, // evict方法也就可以繼續(xù)往下執(zhí)行,進(jìn)行無用服務(wù)剔除操作 if (!this.isSelfPreservationModeEnabled()) { return true; } else { //如果開啟了自我保護(hù)機(jī)制,則進(jìn)一步判斷是否開啟自我保護(hù)機(jī)制 //numberOfRenewsPerMinThreshold(每分鐘最小的續(xù)約次數(shù))大于0 //而且getNumOfRenewsInLastMin(最后一分鐘的續(xù)約次數(shù))必須要大于每分鐘最小的續(xù)約次數(shù) //當(dāng)滿足上面兩個(gè)條件時(shí)則說明續(xù)約正常,返回true,evict方法也就可以繼續(xù)往下執(zhí)行,進(jìn)行無用服務(wù)剔除操作 //所以說,只有不滿足上述兩個(gè)條件的情況下,才會(huì)返回false,evict方法也就不在往下執(zhí)行,即使有沒有正常續(xù)約的服務(wù),也不會(huì)剔除 return this.numberOfRenewsPerMinThreshold > 0 && this.getNumOfRenewsInLastMin() > (long)this.numberOfRenewsPerMinThreshold; } }
第五步,我們注意到numberOfRenewsPerMinThreshold這個(gè)變量很關(guān)鍵,它的含義是每分鐘最小的續(xù)約次數(shù)
在服務(wù)注冊(cè)register和服務(wù)下線cancel兩個(gè)方法中會(huì)更新這個(gè)變量,更新該變量方法如下:
/** * 期望每分鐘最小的續(xù)約次數(shù) = 期望正常續(xù)約的服務(wù)實(shí)例數(shù) * (60/(我們配置的發(fā)送一次心跳時(shí)間間隔(默認(rèn)30秒)))*0.85 * serverConfig.getRenewalPercentThreshold() 默認(rèn)是 0.85 (可以通過eureka.server.renewal-percent-threshold)進(jìn)行配置 **/ protected void updateRenewsPerMinThreshold() { this.numberOfRenewsPerMinThreshold = (int)((double)this.expectedNumberOfClientsSendingRenews * (60.0D / (double)this.serverConfig.getExpectedClientRenewalIntervalSeconds()) * this.serverConfig.getRenewalPercentThreshold()); }
以上就是Eureka開啟自我保護(hù)的整個(gè)邏輯流程。
解除自我保護(hù)機(jī)制
1.當(dāng)服務(wù)的網(wǎng)絡(luò)分區(qū)故障解除之后,客戶端能夠和服務(wù)進(jìn)行交互時(shí),在續(xù)約的時(shí)候,更新每分鐘的續(xù)約數(shù),當(dāng)每分鐘的續(xù)約數(shù)大于85%時(shí),則自動(dòng)解除。
2.重啟服務(wù)
Eureka 的健康檢查
其實(shí)很多框架的健康狀態(tài)監(jiān)控都是通過actuator來管理健康狀態(tài)的,并且擴(kuò)展了health端點(diǎn)。
所以說我們只要在項(xiàng)目中集成Actuator,我們就能管理監(jiān)控項(xiàng)目的健康狀態(tài)。
Eureka也是一樣,我們可以將某些不健康的服務(wù)節(jié)點(diǎn)的狀態(tài)告知Eureka Server,然后Eureka Server 會(huì)主動(dòng)讓其下線。
這個(gè)就是Eureka的健康檢查。
如何實(shí)現(xiàn)Eureka-Actuator健康檢查?
首先我們要在pom中依賴spring-boot-starter-actuator。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> <version>2.3.3.RELEASE</version> </dependency>
第二步,配置文件中添加 eureka.client.healthcheck.enabled=true 配置
原理分析:
首先在EurekaDiscoveryClientConfiguration 中根據(jù) eureka.client.healthcheck.enabled 的值來決定是否要裝配 EurekaHealthCheckHandler,然后在 EurekaClientAutoConfiguration 中會(huì)注冊(cè) HealthCheck,但我們注冊(cè)完成后會(huì)有調(diào)用任務(wù)來進(jìn)行狀態(tài)的更新,在com.netflix.discovery.InstanceInfoReplicator.run() 中會(huì)進(jìn)行狀態(tài)更新。
Eureka 的多級(jí)緩存機(jī)制
什么是多級(jí)緩存機(jī)制
Eureka Server 為了避免同事讀取內(nèi)存數(shù)據(jù)造成的并發(fā)沖突問題,采用了多級(jí)緩存機(jī)制提升服務(wù)請(qǐng)求的響應(yīng)速度。
Eureka Server的緩存是通過一個(gè)只讀,一個(gè)讀寫緩存來實(shí)現(xiàn)的。
一級(jí)緩存:concurrentHashMap<key,value>readOnlyCacheMap本質(zhì)是HashMap,無過期時(shí)間,保存數(shù)據(jù)信息對(duì)外輸出。
readOnlyCacheMap依賴于定時(shí)器的更新,通過與readWriteCacheMap的值做對(duì)比,以readWriteCacheMap為準(zhǔn)。
responseCacheUpdateIntervalMs:readOnlyCacheMap緩存更新間隔,默認(rèn)30s
二級(jí)緩存:LoaDing<key,value>readWriteCacheMap本質(zhì)是Guava緩存,包含失效機(jī)制,保護(hù)數(shù)據(jù)信息對(duì)外輸出。
responseCacheAutoExpirationInSeconds:readWriteCacheMap 緩存過期時(shí)間,默認(rèn)180s。
當(dāng)服務(wù)節(jié)點(diǎn)發(fā)生注冊(cè),下線,過期,狀態(tài)變更等變化時(shí)
1.在內(nèi)存中更新注冊(cè)表信息
2.同時(shí)過期掉readWriteCacheMap緩存,緩存清除只是會(huì)去清除readWriteCacheMap這個(gè)緩存, readOnlyCacheMap 只讀 緩存并沒有更新,也就說當(dāng)客戶端的信息發(fā)生變化之后, 只讀緩存不是第一時(shí)間感知到的。只讀緩存的更新只能依賴那個(gè)30秒的定時(shí)任務(wù)來更新。
3.一段時(shí)間后(默認(rèn)30s),后臺(tái)線程發(fā)現(xiàn)readWriteCacheMap緩存為空,于是也將readOnlyCacheMap中的緩存清空
4.當(dāng)有服務(wù)消費(fèi)者拉取注冊(cè)表信息時(shí),會(huì)調(diào)用ClassLoader的load方法,將內(nèi)存中的注冊(cè)表信息加載到各級(jí)緩存中,并返回注冊(cè)表信息。
在Eureka Server 中會(huì)有兩個(gè)線程,一個(gè)是定時(shí)同步兩個(gè)緩存的數(shù)據(jù),默認(rèn)30s,一個(gè)是定時(shí)檢測(cè)心跳故障,默認(rèn)90s。
服務(wù)拉取
1.服務(wù)消費(fèi)者,默認(rèn)每30s,拉取注冊(cè)表信息
2.從readOnlyCacheMap中獲取信息,如果獲取為空
3.從readWriteCacheMap中獲取,如果還是為空
4.調(diào)用ClassLoader的load方法,將內(nèi)存中的注冊(cè)表信息加載到各級(jí)緩存中,并返回注冊(cè)表信息。
Eureka的區(qū)域配置
當(dāng)用戶地理分布范圍很廣的時(shí)候,比如公司在上海、杭州、青島等都有分公司的時(shí)候,一般都會(huì)有多個(gè)機(jī)房。
那么對(duì)于用戶而言,當(dāng)然是希望調(diào)用本地分公司的機(jī)房中的微服務(wù)應(yīng)用。
比如:上海用戶A,調(diào)用OAuth3服務(wù),用戶A當(dāng)然希望調(diào)用上海機(jī)房里面的微服務(wù)應(yīng)用。如果上海用戶A調(diào)用杭州機(jī)房的OAuth3服務(wù),就增加的延時(shí)時(shí)間。
所以我們希望一個(gè)機(jī)房內(nèi)的服務(wù)優(yōu)先調(diào)用同一個(gè)機(jī)房內(nèi)的服務(wù),當(dāng)同一個(gè)機(jī)房的服務(wù)不可用的時(shí)候,再去調(diào)用其它機(jī)房的服務(wù),以達(dá)到減少延時(shí)的作用。
為此,eureka提供了region和zone兩個(gè)概念來進(jìn)行分區(qū),Eureka基于Amazon設(shè)計(jì)的,所以對(duì)于地域的區(qū)分也與Amazon一致,Amazon分為多個(gè)region,每個(gè)region包含多個(gè)zone,所以Eureka設(shè)計(jì)時(shí)也是可以設(shè)置region與zone,請(qǐng)求時(shí)可以優(yōu)先選擇與請(qǐng)求服務(wù)在同一個(gè)zone的服務(wù)。
基本配置
eureka: client: region: shanghai availability-zones: shanghai: zone1, zone2 service-url: zone1: http://localhost:8081/eureka, http://localhost:8082/eureka zone2: http://localhost:8083/eureka, http://localhost:8084/eureka instance: metadata-map: zone: zone1
此時(shí)無論我們調(diào)用多少次,調(diào)用的都是shanghai下面的zone1下面的服務(wù)。
一般來說我們都會(huì)結(jié)合Ribbon來實(shí)現(xiàn)微服務(wù)的負(fù)載均衡,而Ribbon內(nèi)部會(huì)有一些專門的負(fù)載策略算法,雖然剛剛我們說過會(huì)優(yōu)先請(qǐng)求的是指定region下指定 Zone 區(qū)域的服務(wù)實(shí)例。
但有些時(shí)候比如當(dāng)在Region=shanghai下沒有可用的zone,系統(tǒng)會(huì)默認(rèn)加載 DEFAULT_ZONE,或者說活著同區(qū)域的服務(wù)負(fù)載過高...等等,也會(huì)自動(dòng)切換成其他區(qū)域的服務(wù)。
Eureka的重試機(jī)制
由于 Spring Cloud Eureka 實(shí)現(xiàn)的服務(wù)治理機(jī)制強(qiáng)調(diào)了 CAP 原理中的 AP,即可用性與可靠性,犧牲了一定的一致性(在極端情況下它寧愿接受故障實(shí)例也不要丟掉"健康"實(shí)例,如同如我們上面所說的自我保護(hù)機(jī)制)。
但不論是由于觸發(fā)了保護(hù)機(jī)制還是服務(wù)剔除的延遲,引起服務(wù)調(diào)用到這些不正常的服務(wù),調(diào)用就會(huì)失敗,從而導(dǎo)致其它服務(wù)不能正常工作!
這顯然不是我們?cè)敢饪吹降?,我們還是希望能夠增強(qiáng)對(duì)這類問題的容錯(cuò)。所以,我們?cè)趯?shí)現(xiàn)服務(wù)調(diào)用的時(shí)候通常會(huì)加入一些重試機(jī)制。
從 Camden SR2 版本開始,Spring Cloud 就整合了 Spring Retry 來增強(qiáng) RestTemplate 的重試能力,對(duì)于開發(fā)者來說只需通過簡單的配置,原來那些通過 RestTemplate 實(shí)現(xiàn)的服務(wù)訪問就會(huì)自動(dòng)根據(jù)配置來實(shí)現(xiàn)重試策略。
開啟Eureka的重試機(jī)制很簡單,首先我們?cè)趐om中引入Spring Retry的依賴:
<dependency> <groupId>org.springframework.retry</groupId> <artifactId>spring-retry</artifactId> </dependency>
然后在配置文件中配置spring.cloud.loadbalancer.retry.enabled參數(shù)來控制重試機(jī)制的開關(guān),因?yàn)?nbsp;Spring Retry默認(rèn)是開啟的,所以說我們只要引入依賴即可,如果說我們想要關(guān)閉的話只需要將 spring.cloud.loadbalancer.retry.enabled設(shè)置為false即可。
其實(shí)在SpringCloud的架構(gòu)組件中無論是Fegin,Ribbon,還是Zuul都提供了重試機(jī)制,這些暫且不論,后續(xù)再講到具體的組件時(shí)再進(jìn)行具體的分析。
實(shí)戰(zhàn) Eureka 注冊(cè)中心的部署
Eureka Server 項(xiàng)目搭建
1、創(chuàng)建一個(gè) springcloud-eureka-server 的項(xiàng)目,然后在 pom 中增加 spring-cloud-starter-netflix-eureka-server 的依賴。
2.在pom.xml文件中新增spring-cloud-starter-netflix-eureka-server依賴
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency>
3.在啟動(dòng)類SpringcloudEurekaServerApplication上使用 @EnableEurekaServer 開啟 EurekaServer 的自動(dòng)裝配功能。
@SpringBootApplication @EnableEurekaServer public class SpringcloudEurekaServerApplication { public static void main(String[] args){ SpringApplication.run(SpringcloudEurekaServerApplication.class, args); } }
4.添加配置文件application.properties
# server (eureka 默認(rèn)端口為:8761) server.port=8761 # spring spring.application.name=spring-cloud-eureka-server # eureka # 是否注冊(cè)到eureka eureka.client.register-with-eureka=false # 是否從eureka獲取注冊(cè)信息 eureka.client.fetch-registry=false # eureka服務(wù)器的地址(注意:地址最后面的 /eureka/ 這個(gè)是固定值) eureka.client.serviceUrl.defaultZone=http://localhost:${server.port}/eureka/
5.啟動(dòng)項(xiàng)目,然后訪問http://localhost:8761/,可以看到 Eureka 的管理頁面,表示 Eureka 啟動(dòng)成功了。
1、創(chuàng)建一個(gè) springcloud-eureka-client 的項(xiàng)目,然后在 pom 中增加 spring-cloud-starter-netflix-eureka-client 的依賴。
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency>
2.在啟動(dòng)類SpringcloudEurekaClientApplication上使用 @EnableEurekaClient 開啟 EurekaServer 的自動(dòng)裝配功能。
@SpringBootApplication @EnableEurekaClient public class SpringcloudEurekaClientApplication { public static void main(String[] args) { SpringApplication.run(SpringcloudEurekaClientApplication.class, args); } }
配置 eureka.client.serviceUrl.defaultZone 的地址,也就是剛剛啟動(dòng)的 Eureka Server 的地址,http://localhost:8761/eureka/。
server.port=8762 spring.application.name=spring-cloud-eureka-client eureka.client.serviceUrl.defaultZoon=http://localhost:8761/eureka/
啟動(dòng)客戶端,然后刷新剛剛打開的Eureka主頁,我們發(fā)現(xiàn)服務(wù)已經(jīng)注冊(cè)成功。
Eureka 注冊(cè)中心添加密碼認(rèn)證
上面我們看到我們搭建好Eureka Server 后訪問http://localhost:8761/,沒有登陸就可以直接看到 Eureka 的管理頁面。
如果在實(shí)際使用中,注冊(cè)中心地址有公網(wǎng) IP 的話,必然能直接訪問到,這樣是不安全的。所以我們需要對(duì) Eureka 進(jìn)行改造,通過集成 Spring-Security 來進(jìn)行安全認(rèn)證,加上權(quán)限認(rèn)證來保證安全性。
首先,在 pom.xml 中引入 Spring-Security 的依賴
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency>
然后在 application.properties 中加上認(rèn)證的配置信息
spring.security.user.name=javaer123456 #用戶名 spring.security.user.password=123456 #密碼
最后增加Spring Security 配置類
@Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { // 關(guān)閉 Spring Security 的 CSRF 驗(yàn)證(如果不關(guān)閉,那么客戶端就連接不上) http.csrf().disable(); // 支持httpBasic http.authorizeRequests().anyRequest().authenticated().and().httpBasic(); } }
這樣我們啟動(dòng)Eureka Server成功后在訪問 http://localhost:8761/,此時(shí)瀏覽器會(huì)提示你輸入用戶名和密碼,輸入正確后才能繼續(xù)訪問 Eureka 提供的管理頁面。
注意:在 Eureka Server開啟認(rèn)證后,Eureka Client注冊(cè)的配置也要加上認(rèn)證的用戶名和密碼信息
eureka.client.serviceUrl.defaultZone=http://javaer23456:123456@localhost:8761/eureka/
感謝各位的閱讀,以上就是“什么是Eureka”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對(duì)什么是Eureka這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。