Spring Cloud Eureka服務(wù)注冊與發(fā)現(xiàn)

概述

關(guān)于Eureka

微服務(wù)是當(dāng)前互聯(lián)網(wǎng)系統(tǒng)的主流架構(gòu),而服務(wù)注冊與發(fā)現(xiàn)則是微服務(wù)架構(gòu)的基礎(chǔ),Spring Cloud為我們提供的眾多組件属铁,其中Eureka就是Spring Cloud為我們提供服務(wù)注冊與發(fā)現(xiàn)功能的組件

相關(guān)版本

JDK:1.8
SpringBoot:2.2.5.RELEASE
SpringCloud:Hoxton.SR3

相關(guān)文章

如果對微服務(wù)的概念還不是特別了解黍少,建議先戳一下這篇文章:什么是微服務(wù)架構(gòu)眷茁? - 老劉的回答 - 知乎
https://www.zhihu.com/question/65502802/answer/802678798

本文結(jié)構(gòu)

  1. 為什么需要服務(wù)注冊與發(fā)現(xiàn)
  2. 搭建Eureka服務(wù)注冊中心
  3. 搭建Eureka客戶端實例
  4. 實現(xiàn)Eureka的高可用

Eureka入門

為什么需要服務(wù)注冊與發(fā)現(xiàn)

開始coding之前先了解一下微服務(wù)架構(gòu)中為什么需要服務(wù)注冊與發(fā)現(xiàn)。在微服務(wù)架構(gòu)中知允,存在有多個微小的子服務(wù)撤防,各個子服務(wù)之間需要http通訊,那么肯定需要知道彼此的IP地址咆瘟,那假設(shè)系統(tǒng)中存在ABC三個子服務(wù)存在如下的情況:

  • A調(diào)用BC嚼隘,A存BC的IP
  • B調(diào)用AC,B存AC的IP
  • C調(diào)用AB搞疗,C存AB的IP

ABC都需要在各自的服務(wù)中維護(hù)對方的IP地址嗓蘑,這還只是ABC三個子服務(wù)之間,假設(shè)系統(tǒng)中有100個子服務(wù)呢匿乃?而且一旦某個子服務(wù)的IP發(fā)生改變桩皿,則意味著所有跟它有關(guān)聯(lián)的子服務(wù)都需要修改對應(yīng)的IP地址。顯然這是非常不合理的幢炸,所以我們需要一個服務(wù)注冊與發(fā)現(xiàn)中心的角色泄隔。系統(tǒng)中所有的子服務(wù)在啟動時都注冊到服務(wù)注冊中心,于是所有的子服務(wù)相關(guān)信息都會存儲在服務(wù)注冊中心宛徊,當(dāng)A需要調(diào)用BC時佛嬉,不在需要自己維護(hù)一份其他服務(wù)的IP地址,A可以向服務(wù)注冊中心獲取一份其他服務(wù)的IP地址闸天,如下圖:


服務(wù)注冊

搭建Eureka服務(wù)注冊中心

創(chuàng)建工程
  1. 使用IDEA創(chuàng)建項目暖呕,通過Spring Initianlizr創(chuàng)建項目
    Spring Initianlizr
  2. 輸入工程信息
    工程信息
  3. 依賴選擇Spring Cloud Discovery里面的Eureka Server,最后保存你的項目就行了


    選擇依賴
增加必要注解和修改配置
  1. 先利用@EnableEurekaServer讓此服務(wù)成為注冊中心苞氮,在啟動類上加@EnableEurekaServer
@SpringBootApplication
@EnableEurekaServer
public class EurekaApplication {

    public static void main(String[] args) {
        SpringApplication.run(EurekaApplication.class, args);
    }

}

訪問localhost:8761看看(我配置的端口是8761)


localhost:8761

可以看到Instance currently registered with Eureka列表中實例是空的湾揽,也就是還沒有實例注冊到這個服務(wù)注冊中心。運行的時候發(fā)現(xiàn)console控制臺一直打印com.netflix.discovery.shared.transport.TransportException: Cannot execute request on any known server這個異常,這個異常是是Eureka客戶端實例沒有配置對應(yīng)Eureka服務(wù)注冊中心時會拋出的錯誤库物,這里因為默認(rèn)情況下Eureka服務(wù)注冊中心自己本身也會被作為一個實例注冊到EurekaEureka服務(wù)注冊中心霸旗,這時候因為這個Eureka服務(wù)沒有配置需要注冊到哪個Eureka服務(wù)注冊中心,所以會拋出這個錯誤

  1. 配置文件增加下面的配置(這里用的yml)戚揭,通過register-with-eureka: false配置當(dāng)前這個服務(wù)不要注冊到Eureka服務(wù)注冊中心诱告,一般情況下作為Eureka服務(wù)注冊中心的服務(wù)都會增加這個配置
eureka:
  client:
    register-with-eureka: false

增加這個配置以后,重新啟動民晒,程序運行的時候就不會再出現(xiàn)com.netflix.discovery.shared.transport.TransportException異常了


搭建Eureka客戶端實例

創(chuàng)建工程

和搭建Eureka服務(wù)注冊中心過程類似精居,主要在第三步時選擇Spring Cloud Discovery里面的Eureka Discovery Client,并且注意SpringBoot版本和SpringCloud版本需要和服務(wù)注冊中心服務(wù)保持一致


Eureka Discovery Client
增加必要注解和修改配置
  1. 先加上web依賴镀虐,否則等等項目啟動會失敗
<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
</dependency>
  1. 利用@EnableEurekaClient讓此服務(wù)成為Eureka客戶端實例箱蟆,在啟動類上加@EnableEurekaClient
@SpringBootApplication
@EnableEurekaClient
public class ClientApplication {

    public static void main(String[] args) {
        SpringApplication.run(ClientApplication.class, args);
    }

}
  1. 修改配置文件
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
spring:
  application:
    name: client
  • defaultZone配置當(dāng)前服務(wù)實例需要注冊到的服務(wù)注冊中心的地址
  • name配置當(dāng)前服務(wù)名稱

啟動項目,然后打開/localhost:8761看一下(服務(wù)注冊中心)


服務(wù)注冊中心

可以看到一個名字CLIENT的服務(wù)實例已經(jīng)注冊到服務(wù)注冊中心了刮便。到這就完成了一個最簡單的服務(wù)注冊與發(fā)現(xiàn)過程了


實現(xiàn)Eureka的高可用

為了保證Eureka的高可用空猜,可以通過部署多臺Eureka服務(wù)注冊中心(集群)的方式來實現(xiàn)


Eureka高可用

如上圖所示,建立一個擁有3臺服務(wù)注冊中心的服務(wù)注冊中心集群恨旱,并且各個服務(wù)注冊中心進(jìn)行相互注冊辈毯,然后客戶端實例向每個服務(wù)注冊中心都發(fā)起注冊。

搭建服務(wù)注冊中心集群

這里就以兩個服務(wù)注冊中心為例搜贤,注意我這里為了方便是采取一個工程項目配置兩個SpringBoot啟動谆沃,先看第一個服務(wù)注冊中心我設(shè)置的啟動端口是8761


服務(wù)注冊中心1

然后配置文件里defaultZone把服務(wù)注冊中心1注冊到http://localhost:8762/eureka/,等等第二個服務(wù)注冊中心準(zhǔn)備在8762啟動

eureka:
  client:
    register-with-eureka: false
    service-url:
      defaultZone: http://localhost:8762/eureka/
spring:
  application:
    name: eureka

接著看第二個服務(wù)注冊中心配置的端口仪芒,啟動端口是8762

服務(wù)注冊中心2

再看第二個服務(wù)注冊中心的配置文件唁影,defaultZone把第二個服務(wù)注冊中心注冊到第一個服務(wù)注冊中心的地址http://localhost:8761/eureka/

eureka:
  client:
    register-with-eureka: false
    service-url:
      defaultZone: http://localhost:8761/eureka/

spring:
  application:
    name: eureka
服務(wù)端實例注冊到集群

先啟動上文的兩個服務(wù)注冊中心,先看看如果服務(wù)端實例只注冊到兩個服務(wù)注冊中心的其中一個的情況吧掂名,配置文件配置只注冊到8761

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
spring:
  application:
    name: client

咋們分別進(jìn)localhost:8761和localhost:8762看看据沈,可以發(fā)現(xiàn)雖然實例只注冊到其中一個服務(wù)注冊中心,但是兩個服務(wù)里都發(fā)現(xiàn)這個實例饺蔑,這說明通過服務(wù)注冊中心相互注冊已經(jīng)實現(xiàn)了集群共享注冊實例


實例注冊到集群
真正的高可用

上文已經(jīng)做到服務(wù)注冊中心同步客戶端實例锌介,但是如果這個時候我們把localhost:8761這臺服務(wù)注冊中心(實例注冊到的服務(wù)注冊中心)掛掉會怎樣?先看客戶端實例的控制臺猾警,因為localhost:8761掛掉孔祸,已經(jīng)在打印無法注冊到服務(wù)注冊中心的異常com.netflix.discovery.shared.transport.TransportException: Cannot execute request on any known server。再看看還保持運行的localhost:8762发皿,發(fā)現(xiàn)客戶端實例在localhost:8762中也被清除了崔慧。PS:這里要注意一點,由于Eureka的心跳監(jiān)測機(jī)制(概述中的相關(guān)文章有介紹心跳監(jiān)測)和緩存的問題穴墅,在掛掉localhost:8761以后查看localhost:8762惶室,仍然可以看到客戶端實例在線的狀態(tài)匣屡,需要一定時間以后客戶端實例才會在localhost:8762中清除


客戶端實例掉線

如果localhost:8761掛掉,原本注冊到localhost:8761中的實例在localhost:8762中也會被清除拇涤,那整個服務(wù)注冊中心集群就都失去這個實例的注冊信息,還如何高可用誉结?這時候我們把客戶端實例的配置文件改成defaultZone配置兩個注冊地址

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/, http://localhost:8762/eureka/
spring:
  application:
    name: client

把兩個注冊中心和實例都啟動鹅士,查看一下兩個服務(wù)注冊中心,和上面一樣兩個都注冊上了實例惩坑,不同就在于如果現(xiàn)在把localhost:8761掛掉掉盅,localhost:8762仍舊可以一直保持著實例在線,這樣實例永遠(yuǎn)不會清除以舒,實例會一直注冊在服務(wù)注冊中心集群中趾痘,這是真正的高可用。

一個疑問
  • 很多同學(xué)肯定跟我一樣有一個疑問:客戶端實例的defaultZone配置已經(jīng)修改成同時向兩個注冊中心注冊蔓钟,那兩個注冊中心有沒有相互注冊又有什么關(guān)系永票?就算它們之間沒有相互注冊,一樣可以做到高可用啊
  • 解答:因為客戶端實例defaultZone雖然配置了兩個地址滥沫,但是并不是同時向兩個地址發(fā)起注冊侣集。Eureka的注冊規(guī)則是,從第一個注冊中心地址開始嘗試注冊兰绣,直到最后一個地址世分,如果成功了就不再向其他注冊中心地址發(fā)起注冊。也就是從始至終客戶端實例都是只向一個注冊中心發(fā)起注冊缀辩,集群中的其他注冊中心都是通過同步共享的方式獲得這個客戶端實例的臭埋。所以很顯然,讓服務(wù)注冊中心相互注冊時必要的臀玄,如果沒有相互注冊是做不到同步共享客戶端實例的

總結(jié)

本文源碼地址:https://github.com/iemi/Spring-Cloud-Eureka
如果你覺得本文有幫助到你瓢阴,幫忙點個贊,Github給星星镐牺,感謝炫掐!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市睬涧,隨后出現(xiàn)的幾起案子募胃,更是在濱河造成了極大的恐慌,老刑警劉巖畦浓,帶你破解...
    沈念sama閱讀 218,386評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件痹束,死亡現(xiàn)場離奇詭異,居然都是意外死亡讶请,警方通過查閱死者的電腦和手機(jī)祷嘶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評論 3 394
  • 文/潘曉璐 我一進(jìn)店門屎媳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人论巍,你說我怎么就攤上這事烛谊。” “怎么了嘉汰?”我有些...
    開封第一講書人閱讀 164,704評論 0 353
  • 文/不壞的土叔 我叫張陵丹禀,是天一觀的道長。 經(jīng)常有香客問我鞋怀,道長双泪,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,702評論 1 294
  • 正文 為了忘掉前任密似,我火速辦了婚禮焙矛,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘残腌。我一直安慰自己村斟,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,716評論 6 392
  • 文/花漫 我一把揭開白布抛猫。 她就那樣靜靜地躺著邓梅,像睡著了一般。 火紅的嫁衣襯著肌膚如雪邑滨。 梳的紋絲不亂的頭發(fā)上日缨,一...
    開封第一講書人閱讀 51,573評論 1 305
  • 那天,我揣著相機(jī)與錄音掖看,去河邊找鬼匣距。 笑死,一個胖子當(dāng)著我的面吹牛哎壳,可吹牛的內(nèi)容都是我干的毅待。 我是一名探鬼主播,決...
    沈念sama閱讀 40,314評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼归榕,長吁一口氣:“原來是場噩夢啊……” “哼尸红!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起刹泄,我...
    開封第一講書人閱讀 39,230評論 0 276
  • 序言:老撾萬榮一對情侶失蹤外里,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后特石,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體盅蝗,經(jīng)...
    沈念sama閱讀 45,680評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,873評論 3 336
  • 正文 我和宋清朗相戀三年姆蘸,在試婚紗的時候發(fā)現(xiàn)自己被綠了墩莫。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片芙委。...
    茶點故事閱讀 39,991評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖狂秦,靈堂內(nèi)的尸體忽然破棺而出灌侣,到底是詐尸還是另有隱情,我是刑警寧澤裂问,帶...
    沈念sama閱讀 35,706評論 5 346
  • 正文 年R本政府宣布顶瞳,位于F島的核電站,受9級特大地震影響愕秫,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜焰络,卻給世界環(huán)境...
    茶點故事閱讀 41,329評論 3 330
  • 文/蒙蒙 一戴甩、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧闪彼,春花似錦甜孤、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至描馅,卻和暖如春把夸,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背铭污。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評論 1 270
  • 我被黑心中介騙來泰國打工恋日, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人嘹狞。 一個月前我還...
    沈念sama閱讀 48,158評論 3 370
  • 正文 我出身青樓岂膳,卻偏偏與公主長得像,于是被迫代替她去往敵國和親磅网。 傳聞我的和親對象是個殘疾皇子谈截,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,941評論 2 355

推薦閱讀更多精彩內(nèi)容