二、Eureka注冊(cè)中心

一、Eureka的基礎(chǔ)架構(gòu)

Spring Cloud 封裝了 Netflix 公司開(kāi)發(fā)的 Eureka 模塊來(lái)實(shí)現(xiàn)服務(wù)注冊(cè)和發(fā)現(xiàn)(請(qǐng)對(duì)比Zookeeper)。

Eureka 采用了 C-S 的設(shè)計(jì)架構(gòu)。Eureka Server 作為服務(wù)注冊(cè)功能的服務(wù)器,它是服務(wù)注冊(cè)中心。

而系統(tǒng)中的其他微服務(wù),使用 Eureka 的客戶端連接到 Eureka Server并維持心跳連接。這樣系統(tǒng)的維護(hù)人員就可以通過(guò) Eureka Server 來(lái)監(jiān)控系統(tǒng)中各個(gè)微服務(wù)是否正常運(yùn)行。SpringCloud 的一些其他模塊(比如Zuul)就可以通過(guò) Eureka Server 來(lái)發(fā)現(xiàn)系統(tǒng)中的其他微服務(wù),并執(zhí)行相關(guān)的邏輯。
請(qǐng)注意和Dubbo的架構(gòu)對(duì)比

Eureka包含兩個(gè)組件:Eureka Server和Eureka Client
Eureka Server提供服務(wù)注冊(cè)服務(wù)
各個(gè)節(jié)點(diǎn)啟動(dòng)后,會(huì)在EurekaServer中進(jìn)行注冊(cè),這樣EurekaServer中的服務(wù)注冊(cè)表中將會(huì)存儲(chǔ)所有可用服務(wù)節(jié)點(diǎn)的信息,服務(wù)節(jié)點(diǎn)的信息可以在界面中直觀的看到

EurekaClient是一個(gè)Java客戶端,用于簡(jiǎn)化Eureka Server的交互,客戶端同時(shí)也具備一個(gè)內(nèi)置的、使用輪詢(round-robin)負(fù)載算法的負(fù)載均衡器。在應(yīng)用啟動(dòng)后,將會(huì)向Eureka Server發(fā)送心跳(默認(rèn)周期為30秒)。如果Eureka Server在多個(gè)心跳周期內(nèi)沒(méi)有接收到某個(gè)節(jié)點(diǎn)的心跳,EurekaServer將會(huì)從服務(wù)注冊(cè)表中把這個(gè)服務(wù)節(jié)點(diǎn)移除(默認(rèn)90秒)

二、Eureka三大角色

  • Eureka Server:提供服務(wù)注冊(cè)和發(fā)現(xiàn)
  • Service Provider:服務(wù)提供方將自身服務(wù)注冊(cè)到Eureka,從而使服務(wù)消費(fèi)方能夠找到
  • Service Consumer:服務(wù)消費(fèi)方從Eureka獲取注冊(cè)服務(wù)列表,從而能夠消費(fèi)服務(wù)

三、原理圖

  • Eureka:就是服務(wù)注冊(cè)中心(可以是一個(gè)集群),對(duì)外暴露自己的地址
  • 提供者:?jiǎn)?dòng)后向Eureka注冊(cè)自己信息(地址,提供什么服務(wù))
  • 消費(fèi)者:向Eureka訂閱服務(wù),Eureka會(huì)將對(duì)應(yīng)服務(wù)的所有提供者地址列表發(fā)送給消費(fèi)者,并且定期更新
  • 心跳(續(xù)約):提供者定期通過(guò)http方式向Eureka刷新自己的狀態(tài)

四、入門案例

  • 項(xiàng)目結(jié)構(gòu)


  • 加入依賴

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>cloud-demo</artifactId>
        <groupId>cn.itcast.demo</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>eureka-service</artifactId>

    <dependencies>
        <!-- eureka 服務(wù)端 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <!--<artifactId>spring-cloud-starter-eureka-server</artifactId>-->
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
    </dependencies>

</project>
  • application


  • yml


  • 啟動(dòng)

  1. 引入pom依賴
  2. 添加@EnableEurekaServer注解啟用Eureka服務(wù)
  3. 添加端口
  4. 訪問(wèn)http://127.0.0.1:10086/
  • 啟動(dòng)報(bào)錯(cuò)問(wèn)題分析
    eureka本身既是一個(gè)服務(wù)端也是一個(gè)客戶端
    集群環(huán)境下eureka之間會(huì)進(jìn)行相互注冊(cè),單機(jī)狀態(tài)下無(wú)人可注冊(cè)所以他報(bào)錯(cuò)了
    解決方案
  1. 自己注冊(cè)自己(第一次還是會(huì)報(bào)錯(cuò),因?yàn)槲磫?dòng)好就進(jìn)行注冊(cè),后面不會(huì)報(bào)錯(cuò))



  2. 申明自己端就是注冊(cè)中心,我的職責(zé)就是維護(hù)服務(wù)實(shí)例,并不需要去檢索服務(wù)


五、服務(wù)提供者修改

  • 添加依賴


  • 添加注解


  • 添加配置


六、服務(wù)消費(fèi)者修改

  • 添加依賴


  • 添加注解


  • 添加配置


  • 代碼修改


七、actuator監(jiān)控信息

  • 服務(wù)提供方依賴添加


  • 信息添加


  • 父工程內(nèi)容構(gòu)建


八、Eureka自我保護(hù)

什么是自我保護(hù)模式?

默認(rèn)情況下,如果EurekaServer在一定時(shí)間內(nèi)沒(méi)有接收到某個(gè)微服務(wù)實(shí)例的心跳,EurekaServer將會(huì)注銷該實(shí)例(默認(rèn)90秒)。但是當(dāng)網(wǎng)絡(luò)分區(qū)故障發(fā)生時(shí),微服務(wù)與EurekaServer之間無(wú)法正常通信,以上行為可能變得非常危險(xiǎn)了——因?yàn)槲⒎?wù)本身其實(shí)是健康的,此時(shí)本不應(yīng)該注銷這個(gè)微服務(wù)。Eureka通過(guò)“自我保護(hù)模式”來(lái)解決這個(gè)問(wèn)題——當(dāng)EurekaServer節(jié)點(diǎn)在短時(shí)間內(nèi)丟失過(guò)多客戶端時(shí)(可能發(fā)生了網(wǎng)絡(luò)分區(qū)故障),那么這個(gè)節(jié)點(diǎn)就會(huì)進(jìn)入自我保護(hù)模式。一旦進(jìn)入該模式,EurekaServer就會(huì)保護(hù)服務(wù)注冊(cè)表中的信息,不再刪除服務(wù)注冊(cè)表中的數(shù)據(jù)(也就是不會(huì)注銷任何微服務(wù))。當(dāng)網(wǎng)絡(luò)故障恢復(fù)后,該Eureka Server節(jié)點(diǎn)會(huì)自動(dòng)退出自我保護(hù)模式。

在自我保護(hù)模式中,Eureka Server會(huì)保護(hù)服務(wù)注冊(cè)表中的信息,不再注銷任何服務(wù)實(shí)例。當(dāng)它收到的心跳數(shù)重新恢復(fù)到閾值以上時(shí),該Eureka Server節(jié)點(diǎn)就會(huì)自動(dòng)退出自我保護(hù)模式。它的設(shè)計(jì)哲學(xué)就是寧可保留錯(cuò)誤的服務(wù)注冊(cè)信息,也不盲目注銷任何可能健康的服務(wù)實(shí)例。一句話講解:好死不如賴活著

綜上,自我保護(hù)模式是一種應(yīng)對(duì)網(wǎng)絡(luò)異常的安全保護(hù)措施。它的架構(gòu)哲學(xué)是寧可同時(shí)保留所有微服務(wù)(健康的微服務(wù)和不健康的微服務(wù)都會(huì)保留),也不盲目注銷任何健康的微服務(wù)。使用自我保護(hù)模式,可以讓Eureka集群更加的健壯、穩(wěn)定。

在Spring Cloud中,可以使用eureka.server.enable-self-preservation = false 禁用自我保護(hù)模式。

九、Eureka詳解

接下來(lái)我們?cè)敿?xì)講解Eureka的原理及配置。

9.1 基礎(chǔ)架構(gòu)

Eureka架構(gòu)中的三個(gè)核心角色:

  • 服務(wù)注冊(cè)中心
    Eureka的服務(wù)端應(yīng)用,提供服務(wù)注冊(cè)和發(fā)現(xiàn)功能,就是剛剛我們建立的eureka-demo
  • 服務(wù)提供者
    提供服務(wù)的應(yīng)用,可以是SpringBoot應(yīng)用,也可以是其它任意技術(shù)實(shí)現(xiàn),只要對(duì)外提供的是Rest風(fēng)格服務(wù)即可。本例中就是我們實(shí)現(xiàn)的user-service-demo
  • 服務(wù)消費(fèi)者
    消費(fèi)應(yīng)用從注冊(cè)中心獲取服務(wù)列表,從而得知每個(gè)服務(wù)方的信息,知道去哪里調(diào)用服務(wù)方。本例中就是我們實(shí)現(xiàn)的consumer-demo
9.2 高可用的Eureka Server

Eureka Server即服務(wù)的注冊(cè)中心,在剛才的案例中,我們只有一個(gè)EurekaServer,事實(shí)上EurekaServer也可以是一個(gè)集群,形成高可用的Eureka中心。

服務(wù)同步

多個(gè)Eureka Server之間也會(huì)互相注冊(cè)為服務(wù),當(dāng)服務(wù)提供者注冊(cè)到Eureka Server集群中的某個(gè)節(jié)點(diǎn)時(shí),該節(jié)點(diǎn)會(huì)把服務(wù)的信息同步給集群中的每個(gè)節(jié)點(diǎn),從而實(shí)現(xiàn)數(shù)據(jù)同步。因此,無(wú)論客戶端訪問(wèn)到Eureka Server集群中的任意一個(gè)節(jié)點(diǎn),都可以獲取到完整的服務(wù)列表信息。

動(dòng)手搭建高可用的EurekaServer

我們假設(shè)要搭建兩條EurekaServer的集群,端口分別為:10086和10087

  1. 復(fù)制EurekaServer
  • 第一種


  • 第二種



相互注冊(cè)
  1. 提供方跟消費(fèi)方多地址添加



9.2 服務(wù)提供者

服務(wù)注冊(cè)

服務(wù)提供者在啟動(dòng)時(shí),會(huì)檢測(cè)配置屬性中的:eureka.client.register-with-erueka=true參數(shù)是否正確,事實(shí)上默認(rèn)就是true。如果值確實(shí)為true,則會(huì)向EurekaServer發(fā)起一個(gè)Rest請(qǐng)求,并攜帶自己的元數(shù)據(jù)信息,Eureka Server會(huì)把這些信息保存到一個(gè)雙層Map結(jié)構(gòu)中。第一層Map的Key就是服務(wù)名稱,第二層Map的key是服務(wù)的實(shí)例id。

服務(wù)續(xù)約

在注冊(cè)服務(wù)完成以后,服務(wù)提供者會(huì)維持一個(gè)心跳(定時(shí)向EurekaServer發(fā)起Rest請(qǐng)求),告訴EurekaServer:“我還活著”。這個(gè)我們稱為服務(wù)的續(xù)約(renew);

有兩個(gè)重要參數(shù)可以修改服務(wù)續(xù)約的行為:

也就是說(shuō),默認(rèn)情況下每個(gè)30秒服務(wù)會(huì)向注冊(cè)中心發(fā)送一次心跳,證明自己還活著。如果超過(guò)90秒沒(méi)有發(fā)送心跳,EurekaServer就會(huì)認(rèn)為該服務(wù)宕機(jī),會(huì)從服務(wù)列表中移除,這兩個(gè)值在生產(chǎn)環(huán)境不要修改,默認(rèn)即可。

但是在開(kāi)發(fā)時(shí),這個(gè)值有點(diǎn)太長(zhǎng)了,經(jīng)常我們關(guān)掉一個(gè)服務(wù),會(huì)發(fā)現(xiàn)Eureka依然認(rèn)為服務(wù)在活著。所以我們?cè)陂_(kāi)發(fā)階段可以適當(dāng)調(diào)小。

實(shí)例id

先來(lái)看一下服務(wù)狀態(tài)信息:

在Eureka監(jiān)控頁(yè)面,查看服務(wù)注冊(cè)信息:


在status一列中,顯示以下信息:

  • UP(1):代表現(xiàn)在是啟動(dòng)了1個(gè)示例,沒(méi)有集群
  • DESKTOP-2MVEC12:user-service:8081:是示例的名稱(instance-id),
    • 默認(rèn)格式是:${hostname} + ${spring.application.name} + ${server.port}
    • instance-id是區(qū)分同一服務(wù)的不同實(shí)例的唯一標(biāo)準(zhǔn),因此不能重復(fù)。

我們可以通過(guò)instance-id屬性來(lái)修改它的構(gòu)成:

eureka:
  instance:
    instance-id: ${spring.application.name}:${server.port}

重啟服務(wù)再試試看:


9.3 服務(wù)消費(fèi)者

獲取服務(wù)列表

當(dāng)服務(wù)消費(fèi)者啟動(dòng)是,會(huì)檢測(cè)eureka.client.fetch-registry=true參數(shù)的值,如果為true,則會(huì)從Eureka Server服務(wù)的列表只讀備份,然后緩存在本地。并且每隔30秒會(huì)重新獲取并更新數(shù)據(jù)。我們可以通過(guò)下面的參數(shù)來(lái)修改:

eureka:
  client:
    registry-fetch-interval-seconds: 5

生產(chǎn)環(huán)境中,我們不需要修改這個(gè)值。

但是為了開(kāi)發(fā)環(huán)境下,能夠快速得到服務(wù)的最新?tīng)顟B(tài),我們可以將其設(shè)置小一點(diǎn)。

9.4 失效剔除和自我保護(hù)

失效剔除

有些時(shí)候,我們的服務(wù)提供方并不一定會(huì)正常下線,可能因?yàn)閮?nèi)存溢出、網(wǎng)絡(luò)故障等原因?qū)е路?wù)無(wú)法正常工作。Eureka Server需要將這樣的服務(wù)剔除出服務(wù)列表。因此它會(huì)開(kāi)啟一個(gè)定時(shí)任務(wù),每隔60秒對(duì)所有失效的服務(wù)(超過(guò)90秒未響應(yīng))進(jìn)行剔除。

可以通過(guò)eureka.server.eviction-interval-timer-in-ms參數(shù)對(duì)其進(jìn)行修改,單位是毫秒,生成環(huán)境不要修改。

這個(gè)會(huì)對(duì)我們開(kāi)發(fā)帶來(lái)極大的不變,你對(duì)服務(wù)重啟,隔了60秒Eureka才反應(yīng)過(guò)來(lái)。開(kāi)發(fā)階段可以適當(dāng)調(diào)整,比如10S

自我保護(hù)

我們關(guān)停一個(gè)服務(wù),就會(huì)在Eureka面板看到一條警告:


這是觸發(fā)了Eureka的自我保護(hù)機(jī)制。當(dāng)一個(gè)服務(wù)未按時(shí)進(jìn)行心跳續(xù)約時(shí),Eureka會(huì)統(tǒng)計(jì)最近15分鐘心跳失敗的服務(wù)實(shí)例的比例是否超過(guò)了85%。在生產(chǎn)環(huán)境下,因?yàn)榫W(wǎng)絡(luò)延遲等原因,心跳失敗實(shí)例的比例很有可能超標(biāo),但是此時(shí)就把服務(wù)剔除列表并不妥當(dāng),因?yàn)榉?wù)可能沒(méi)有宕機(jī)。Eureka就會(huì)把當(dāng)前實(shí)例的注冊(cè)信息保護(hù)起來(lái),不予剔除。生產(chǎn)環(huán)境下這很有效,保證了大多數(shù)服務(wù)依然可用。

但是這給我們的開(kāi)發(fā)帶來(lái)了麻煩, 因此開(kāi)發(fā)階段我們都會(huì)關(guān)閉自我保護(hù)模式:

eureka:
  server:
    enable-self-preservation: false # 關(guān)閉自我保護(hù)模式(缺省為打開(kāi))
    eviction-interval-timer-in-ms: 1000 # 掃描失效服務(wù)的間隔時(shí)間(缺省為60*1000ms 失效剔除)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容