跟我學(xué)Spring Cloud(Finchley版)-06-服務(wù)注冊(cè)與服務(wù)發(fā)現(xiàn)-Eureka深入

跟我學(xué)Spring Cloud(Finchley版)-05-服務(wù)注冊(cè)與服務(wù)發(fā)現(xiàn)-Eureka入門(mén) 一節(jié)中,已經(jīng)編寫(xiě)了一個(gè)Eureka Server叮贩,并將服務(wù)提供者與消費(fèi)者都注冊(cè)到了Eureka Server上量瓜。

本節(jié)贷祈,來(lái)深入探討Eureka的高級(jí)特性滓侍。

Eureka原理

本節(jié)來(lái)探討Eureka的原理。

Region & Availability Zone

下面分析一下Eureka原理廉油,在分析原理前惠险,先來(lái)了解一下Region和Availability Zone,如下圖抒线。

圖-Region And Availibility Zone

眾所周知班巩,Netflix公司將他們的應(yīng)用都部署在了AWS上,所以Eureka的架構(gòu)使用到了AWS中的一些概念——不用擔(dān)心嘶炭,這不是說(shuō)Eureka和AWS環(huán)境綁定抱慌,Eureka可以部署在任意環(huán)境

Region和Availability Zone均是AWS的概念眨猎。

  • Region表示AWS中的地理位置抑进,例如us-east-1、us-east-2睡陪、eu-west-1等寺渗;
  • 每個(gè)Region都有多個(gè)Availability Zone夕凝,彼此內(nèi)網(wǎng)打通
  • 各個(gè)Region之間完全隔離户秤,彼此內(nèi)網(wǎng)不打通
  • AWS通過(guò)這種方式實(shí)現(xiàn)了最大的容錯(cuò)和穩(wěn)定性逮矛。

Spring Cloud中鸡号,默認(rèn)使用的Region是us-east-1 。非AWS環(huán)境下须鼎,可將將Region理解為內(nèi)網(wǎng)沒(méi)有打通的機(jī)房鲸伴,將Availability Zone理解成相同機(jī)房的不同機(jī)架(內(nèi)網(wǎng)打通)。

拓展閱讀

Eureka架構(gòu)詳解

Eureka架構(gòu)

如圖是Eureka集群的工作原理裹唆。圖中的組件非常多,概念也比較抽象只洒,我們先來(lái)用通俗易懂的文字翻譯一下:

  • Application Service:服務(wù)提供者许帐;

  • Application Client:服務(wù)消費(fèi)者;

  • Make Remote Call調(diào)用RESTful API毕谴;

  • us-east-1c成畦、us-east-1d等都是Availability Zone,它們都屬于us-east-1這個(gè)region涝开。

由圖可知循帐,Eureka包含兩個(gè)組件:Eureka Server 和 Eureka Client,它們的作用如下:

  • Eureka Server提供服務(wù)發(fā)現(xiàn)的能力忠寻,各個(gè)微服務(wù)啟動(dòng)時(shí)惧浴,會(huì)向Eureka Server注冊(cè)自己的信息(例如IP、端口奕剃、微服務(wù)名稱(chēng)等)衷旅,Eureka Server會(huì)存儲(chǔ)這些信息;

  • Eureka Client是一個(gè)Java客戶(hù)端纵朋,用于簡(jiǎn)化與Eureka Server的交互柿顶;

  • 微服務(wù)啟動(dòng)后,會(huì)周期性(默認(rèn)30秒)地向Eureka Server發(fā)送心跳以續(xù)約自己的“租期”操软;

  • 如果Eureka Server在一定時(shí)間內(nèi)沒(méi)有接收到某個(gè)微服務(wù)實(shí)例的心跳嘁锯,Eureka Server將會(huì)注銷(xiāo)該實(shí)例(默認(rèn)90秒);

  • 默認(rèn)情況下,Eureka Server同時(shí)也是Eureka Client家乘。多個(gè)Eureka Server實(shí)例蝗羊,互相之間通過(guò)增量復(fù)制的方式,來(lái)實(shí)現(xiàn)服務(wù)注冊(cè)表中數(shù)據(jù)的同步仁锯。Eureka Server默認(rèn)保證在90秒內(nèi)耀找,Eureka Server集群內(nèi)的所有實(shí)例中的數(shù)據(jù)達(dá)到一致(從這個(gè)架構(gòu)來(lái)看,Eureka Server所有實(shí)例所處的角色都是對(duì)等的业崖,沒(méi)有類(lèi)似Zookeeper野芒、Consul、Etcd等軟件的選舉過(guò)程双炕,也不存在主從狞悲,所有的節(jié)點(diǎn)都是主節(jié)點(diǎn)。Eureka官方將Eureka Server集群中的所有實(shí)例稱(chēng)為“對(duì)等體(peer)”)

  • Eureka Client會(huì)緩存服務(wù)注冊(cè)表中的信息妇斤。這種方式有一定的優(yōu)勢(shì)——首先摇锋,微服務(wù)無(wú)需每次請(qǐng)求都查詢(xún)Eureka Server,從而降低了Eureka Server的壓力站超;其次乱投,即使Eureka Server所有節(jié)點(diǎn)都宕掉,服務(wù)消費(fèi)者依然可以使用緩存中的信息找到服務(wù)提供者并完成調(diào)用顷编。

綜上戚炫,Eureka通過(guò)心跳檢查、客戶(hù)端緩存等機(jī)制媳纬,提高了系統(tǒng)的靈活性双肤、可伸縮性和可用性。

TIPS

事實(shí)上钮惠,這個(gè)官方架構(gòu)圖是有一點(diǎn)問(wèn)題的:Eureka Server本身也集成了Eureka Client茅糜,彼此通過(guò)Eureka Client同步數(shù)據(jù)給其它實(shí)例又或者從其他實(shí)例同步數(shù)據(jù)——現(xiàn)在,你應(yīng)該能理解上一節(jié)中所使用的 register-with-eureka 以及fetch-registry 的作用了素挽。

高可用

編寫(xiě)高可用Eureka Server

下面來(lái)編寫(xiě)一個(gè)雙節(jié)點(diǎn)Eureka Server集群蔑赘。編寫(xiě)這個(gè)集群非常簡(jiǎn)單,只需修改單實(shí)例Eureka Server的配置即可:

  • 為系統(tǒng)配置主機(jī)名:
    vim /etc/hosts
    # 添加如下內(nèi)容
    127.0.0.1 peer1 peer2

    對(duì)于Windows系統(tǒng)预明,請(qǐng)修改C:\windows\system32\drivers\etc\hosts文件
  • 配置:
spring:
  application:
    name: microservice-discovery-eureka-ha
---
spring:
  profiles: peer1                                 # 指定profile=peer1
server:
  port: 8761
eureka:
  instance:
    hostname: peer1                               # 指定當(dāng)profile=peer1時(shí)缩赛,主機(jī)名是peer1
  client:
    serviceUrl:
      defaultZone: http://peer2:8762/eureka/      # 將自己注冊(cè)到peer2這個(gè)Eureka上面去
---
spring:
  profiles: peer2
server:
  port: 8762
eureka:
  instance:
    hostname: peer2
  client:
    serviceUrl:
      defaultZone: http://peer1:8761/eureka/
由配置不難看出我們?cè)O(shè)置了兩個(gè)Profile:peer1、peer2撰糠。兩個(gè)Profile下各有一個(gè)Eureka Server酥馍,通過(guò)相互注冊(cè)的方式,構(gòu)建了Eureka Server集群阅酪。
  • 啟動(dòng):
  java -jar microservice-discovery-eureka-ha-0.0.1-SNAPSHOT.jar --spring.profiles.active=peer1
  java -jar microservice-discovery-eureka-ha-0.0.1-SNAPSHOT.jar --spring.profiles.active=peer2
第一個(gè)實(shí)例會(huì)報(bào)錯(cuò)旨袒,這是正常的汁针,因?yàn)樗鼤?huì)嘗試連接第二個(gè)實(shí)例,但第二個(gè)實(shí)例尚未啟動(dòng)砚尽,所以會(huì)報(bào)連接不上的異常施无。

注意點(diǎn)

  • 如果兩個(gè)Eureka Server實(shí)例在同一臺(tái)機(jī)器上啟動(dòng),那么配置hosts的這一步不能少必孤。原因:Eureka Server對(duì)端口是不敏感的帆精,這意味著,如果直接用IP的形式(例如地址寫(xiě)成http://127.0.0.1:8761/eureka/)相互注冊(cè)隧魄,Eureka Server誤認(rèn)為兩個(gè)Eureka Server實(shí)例是一個(gè)實(shí)例——這會(huì)造成Eureka Server首頁(yè)顯示不正常等一系列問(wèn)題!隘蝎!

拓展閱讀

TIPS

編寫(xiě)Eureka Server集群的簡(jiǎn)寫(xiě)方式:

spring:
  application:
    name: microservice-discovery-eureka-ha
eureka:
  client:
    serviceUrl:
      defaultZone: http://peer2:8762/eureka/,http://peer1:8761/eureka/
---
spring:
  profiles: peer1
server:
  port: 8761
eureka:
  instance:
    hostname: peer1
---
spring:
  profiles: peer2
server:
  port: 8762
eureka:
  instance:
    hostname: peer2

將應(yīng)用注冊(cè)到Eureka Server集群上

microservice-provider-user 項(xiàng)目為例,只須修改eureka.client.serviceUrl.defaultZone嘱么,配置多個(gè)Eureka Server地址狮含,就可以將其注冊(cè)到Eureka Server集群了。示例:

eureka:
 client:
   serviceUrl:
     defaultZone: http://peer1:8761/eureka/,http://peer2:8762/eureka/

這樣就可以將服務(wù)注冊(cè)到Eureka Server集群上了曼振。

當(dāng)然几迄,微服務(wù)即使只配置Eureka Server集群中的某個(gè)節(jié)點(diǎn),也能正常注冊(cè)到Eureka Server集群冰评,因?yàn)槎鄠€(gè)Eureka Server之間的數(shù)據(jù)會(huì)相互同步映胁。例如:

eureka:
 client:
   serviceUrl:
     defaultZone: http://peer1:8761/eureka/

正常情況下,這種方式與配置多個(gè)Server節(jié)點(diǎn)的效果是一樣的甲雅。不過(guò)為適應(yīng)某些極端場(chǎng)景解孙,筆者建議在客戶(hù)端配置多個(gè)Eureka Server節(jié)點(diǎn)。

應(yīng)用啟動(dòng)后抛人,訪問(wèn)Eureka Server應(yīng)能看到類(lèi)似如下的界面:

Eureka集群首頁(yè)

RESTful API

前文說(shuō)過(guò)弛姜,Eureka本身是一個(gè)基于REST的服務(wù)。本節(jié)來(lái)探討Eureka Server的RESTful API妖枚。

下表展示了Eureka Server提供的RESTful API廷臼,來(lái)自https://github.com/Netflix/eureka/wiki/Eureka-REST-operations ,只需按表格向Eureka Server發(fā)送請(qǐng)求绝页,即可操作Eureka Server中的數(shù)據(jù)荠商。

Operation HTTP action Description
Register new application instance POST /eureka/apps/appID Input:JSON/XMLpayload HTTPCode: 204 on success
De-register application instance DELETE /eureka/apps/appID/instanceID HTTP Code: 200 on success
Send application instance heartbeat PUT /eureka/apps/appID/instanceID HTTP Code:* 200 on success* 404 if instanceID doesn’t exist
Query for all instances GET /eureka/apps HTTP Code: 200 on success Output:JSON/XML
Query for all appIDinstances GET /eureka/apps/appID HTTP Code: 200 on success Output:JSON/XML
Query for a specificappID/instanceID GET /eureka/apps/appID/instanceID HTTP Code: 200 on success Output:JSON/XML
Query for a specificinstanceID GET /eureka/instances/instanceID HTTP Code: 200 on success Output:JSON/XML
Take instance out of service PUT /eureka/apps/appID/instanceID/status?value=OUT_OF_SERVICE HTTP Code:* 200 on success* 500 on failure
Put instance back into service (remove override) DELETE /eureka/apps/appID/instanceID/status?value=UP (The value=UP is optional, it is used as a suggestion for the fallback status due to removal of the override) HTTP Code:* 200 on success* 500 on failure
Update metadata PUT /eureka/apps/appID/instanceID/metadata?key=value HTTP Code:* 200 on success* 500 on failure
Query for all instances under a particular vip address GET /eureka/vips/vipAddress HTTP Code: 200 on success Output:JSON/XML 404 if thevipAddress**does not exist.
Query for all instances under a particular secure vip address GET /eureka/svips/svipAddress HTTP Code: 200 on success Output:JSON/XML 404 if thesvipAddress**does not exist.

調(diào)用示例

示例1:注冊(cè)一個(gè)服務(wù):

  • 將以下文件存儲(chǔ)為rest-api-test.xml
<instance>
     <instanceId>itmuch:rest-api-test:9000</instanceId>
     <hostName>itmuch</hostName>
     <app>REST-API-TEST</app>
     <ipAddr>127.0.0.1</ipAddr>
     <vipAddress>rest-api-test</vipAddress>
     <secureVipAddress>rest-api-test</secureVipAddress>
     <status>UP</status>
     <port enabled="true">9000</port>
     <securePort enabled="false">443</securePort>
     <homePageUrl>http://127.0.0.1:9000/</homePageUrl>
     <statusPageUrl>http://127.0.0.1:9000/info</statusPageUrl>
     <healthCheckUrl>http://127.0.0.1:9000/health</healthCheckUrl>
     <dataCenterInfo class="com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo">
     <name>MyOwn</name>
     </dataCenterInfo>
</instance>
  • 通過(guò)cURL調(diào)用Eureka Server
cat ./rest-api-test.xml | curl -v -X POST -H "Content-type: application/xml" -d @- http://localhost:8761/eureka/apps/rest-api-test

示例2:查看指定服務(wù)的所注冊(cè)的信息

只需訪問(wèn):http://Eureka Server的地址/eureka/apps/microservice-provider-user 即可查看microdervice-provider-user 服務(wù)的信息。

RESTful API的意義

你可能會(huì)問(wèn):我們不是已經(jīng)有Eureka Client了嗎续誉?誰(shuí)閑著沒(méi)事再去用RESTful API敖崽洹?

要知道屈芜,微服務(wù)的優(yōu)勢(shì)之一就是允許使用異構(gòu)的技術(shù)郊愧、異構(gòu)的語(yǔ)言甚至異構(gòu)的平臺(tái)解決你想解決的問(wèn)題朴译。

舉個(gè)例子,如果你有一個(gè)系統(tǒng)属铁,一部分是Spring Cloud構(gòu)建的眠寿,一部分是用世界上最好的語(yǔ)言PHP寫(xiě)的!但是呢焦蘑,你希望Java應(yīng)用與PHP應(yīng)用之間的通信也能享受服務(wù)發(fā)現(xiàn)所帶來(lái)的好處盯拱,此時(shí)就可編寫(xiě)一個(gè)基于PHP的Eureka Client,將PHP應(yīng)用也注冊(cè)到Eureka Server例嘱!

事實(shí)上狡逢,前文說(shuō)的Eureka Client不過(guò)是一個(gè)用Jersey 1.x封裝了RESTful API的Jar包而已

拓展閱讀
事實(shí)上拼卵,業(yè)界已經(jīng)有一些不同語(yǔ)言的Eureka Client奢浑,例如:

自我保護(hù)模式

自我保護(hù)模式是Eureka的重要特性,筆者之前已經(jīng)專(zhuān)題寫(xiě)過(guò)文章詳解了腋腮,所以本系列不再贅述雀彼,詳見(jiàn):理解Eureka的自我保護(hù)模式

用戶(hù)認(rèn)證

Finchley版本相對(duì)之前的版本有些改動(dòng),比較重要即寡。詳見(jiàn): 跟我學(xué)Spring Cloud(Finchley版)番外-01-Eureka安全詳解 徊哑。

配套代碼

相關(guān)文章

本文鏈接跟我學(xué)Spring Cloud(Finchley版)-06-服務(wù)注冊(cè)與服務(wù)發(fā)現(xiàn)-Eureka深入

轉(zhuǎn)載聲明:本博客由周立創(chuàng)作莺丑,采用 CC BY 3.0 CN 許可協(xié)議《章可自由轉(zhuǎn)載窒盐、引用,但需署名作者且注明文章出處钢拧。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末蟹漓,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子源内,更是在濱河造成了極大的恐慌葡粒,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件膜钓,死亡現(xiàn)場(chǎng)離奇詭異嗽交,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)颂斜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門(mén)夫壁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人沃疮,你說(shuō)我怎么就攤上這事盒让∶贩簦” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵邑茄,是天一觀的道長(zhǎng)姨蝴。 經(jīng)常有香客問(wèn)我,道長(zhǎng)肺缕,這世上最難降的妖魔是什么左医? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮同木,結(jié)果婚禮上浮梢,老公的妹妹穿的比我還像新娘。我一直安慰自己彤路,他們只是感情好秕硝,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著斩萌,像睡著了一般。 火紅的嫁衣襯著肌膚如雪屏轰。 梳的紋絲不亂的頭發(fā)上颊郎,一...
    開(kāi)封第一講書(shū)人閱讀 51,292評(píng)論 1 301
  • 那天,我揣著相機(jī)與錄音霎苗,去河邊找鬼姆吭。 笑死,一個(gè)胖子當(dāng)著我的面吹牛唁盏,可吹牛的內(nèi)容都是我干的内狸。 我是一名探鬼主播,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼厘擂,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼昆淡!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起刽严,我...
    開(kāi)封第一講書(shū)人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤昂灵,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后舞萄,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體眨补,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡酿雪,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年权她,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了理卑。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片曹宴。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡亲怠,死狀恐怖纤虽,靈堂內(nèi)的尸體忽然破棺而出狐血,到底是詐尸還是另有隱情脖镀,我是刑警寧澤,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布安皱,位于F島的核電站调鬓,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏酌伊。R本人自食惡果不足惜腾窝,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望居砖。 院中可真熱鬧虹脯,春花似錦、人聲如沸奏候。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)蔗草。三九已至咒彤,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間咒精,已是汗流浹背镶柱。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留模叙,地道東北人歇拆。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像范咨,于是被迫代替她去往敵國(guó)和親故觅。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354