分布式系統(tǒng)開發(fā)技術(shù) | Eureka服務(wù)注冊與發(fā)現(xiàn)

本文章是在網(wǎng)易云課堂的課程學(xué)習(xí)中編寫,部分圖片從網(wǎng)易云課堂ppt引用

一、什么是Eureka注冊中心

各個服務(wù)注冊到Eureka,Eureka對服務(wù)進行管理:
1、可感知注冊的服務(wù)的健康情況,是否下線
2、可感知注冊的服務(wù)的IP和Port地址變更

注:若使用nginx,nginx無法感知注冊的服務(wù)是否下線,且若變更服務(wù)地址,需改動nginx配置

Eureka使用圖示:

image.png

說明:
服務(wù)提供者啟動時:定時向EurekaServer注冊自己的服務(wù)信息(服務(wù)名、IP、端口..等等)
服務(wù)消費者啟動時:后臺定時拉取Eureka-Server中存儲的服務(wù)信息

二、如何集成Eureka

1. Eureka注冊中心

1.1 maven引入

<properties>
     <java.version>1.8</java.version>
     <spring-cloud.version>Greenwich.SR1</spring-cloud.version>
 </properties>

 <dependencies>
     <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-actuator</artifactId>
     </dependency>
     <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-web</artifactId>
     </dependency>

     <dependency>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
     </dependency>

     <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-test</artifactId>
         <scope>test</scope>
     </dependency>
 </dependencies>

 <dependencyManagement>
     <dependencies>
         <dependency>
             <groupId>org.springframework.cloud</groupId>
             <artifactId>spring-cloud-dependencies</artifactId>
             <version>${spring-cloud.version}</version>
             <type>pom</type>
             <scope>import</scope>
         </dependency>
     </dependencies>
 </dependencyManagement>

 <build>
     <plugins>
         <plugin>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-maven-plugin</artifactId>
         </plugin>
     </plugins>
 </build>

1.2 代碼

在Application使用 @EnableEurekaServer 注解

1.3 yml配置

spring:
 application:
   name: eureka-peer
 profiles: dev

server:
 port: 10000

eureka:
 #實例
 instance:
   hostname: dev
   instance-id: dev
 #作為客戶端的配置
 client:
   #是否從eureka拉取信息
   fetch-registry: false
   #是否將自己注冊到eureka
   register-with-eureka: false
   #定義區(qū)域,進行分區(qū)。使得調(diào)用更加方便快捷,適用于非常大的服務(wù)器
   #availability-zones:
     #beijing: zone-1
   service-url:
     #默認(rèn)的注冊中心的通信地址
     defaultZone: http://localhost:10000/eureka/,http://localhost:10001/eureka/,http://localhost:10002/eureka/
     #beijing對應(yīng)區(qū)域的通信地址,若該區(qū)域沒有找到服務(wù),再嘗試去訪問別的區(qū)域
     #zone-1: http://localhost:10000/eureka/
 #作為服務(wù)端的配置
 server:
     #服務(wù)間請求的等待時長
     wait-time-in-ms-when-sync-empty: 0
     #自我保護機制
     enable-self-preservation: true
     #同步時長
     peer-eureka-nodes-update-interval-ms: 10000

啟動工程,網(wǎng)頁打開 localhost:10000 可以看到Eureka頁面:

image.png

1.4 調(diào)用鏈路

在配置文件中,可加入日志級別的配置,查看調(diào)用鏈路信息,用來排查問題

logging.level.org.springframework.cloud = debug
logging.level.com.netflix = debug

2. 生產(chǎn)者(服務(wù)提供者)

2.1 maven引入

<properties>
     <java.version>1.8</java.version>
     <spring-cloud.version>Greenwich.RELEASE</spring-cloud.version>
 </properties>

 <dependencies>
     <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter</artifactId>
     </dependency>

     <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-test</artifactId>
         <scope>test</scope>
     </dependency>

     <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-actuator</artifactId>
     </dependency>
     <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-web</artifactId>
     </dependency>

     <dependency>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
         <version>2.1.1.RELEASE</version>
     </dependency>

     <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-test</artifactId>
         <scope>test</scope>
     </dependency>

 </dependencies>

 <dependencyManagement>
     <dependencies>
         <dependency>
             <groupId>org.springframework.cloud</groupId>
             <artifactId>spring-cloud-dependencies</artifactId>
             <version>${spring-cloud.version}</version>
             <type>pom</type>
             <scope>import</scope>
         </dependency>
     </dependencies>
 </dependencyManagement>

 <repositories>
     <repository>
         <id>spring-milestones</id>
         <name>Spring Milestones</name>
         <url>https://repo.spring.io/milestone</url>
     </repository>
 </repositories>

 <build>
     <plugins>
         <plugin>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-maven-plugin</artifactId>
         </plugin>
     </plugins>
 </build>

2.2 代碼示例

在Application使用 @EnableEurekaClient 注解。這里配置2個服務(wù)提供者
服務(wù)提供者1:

@SpringBootApplication
@EnableEurekaClient
@RestController
public class HelloDemoPeer1Application {

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

 @GetMapping("")
 public Object index(){
      String str =  "這是服務(wù)端1返回的應(yīng)答";
     return new String(str);
 }
 
}

服務(wù)提供者2:

@SpringBootApplication
@EnableDiscoveryClient
@EnableEurekaClient
@RestController
@RefreshScope
public class HelloDemoPeer1Application {

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

 @GetMapping("")
 public Object index(){
     String str =  "這是服務(wù)端2返回的應(yīng)答";
     return new String(str);
 }

}

2.3 yml配置

服務(wù)提供者1:

server:
 port: 8001
spring:
 application:
     name: helloserver

eureka:
 client:
     service-url:
         defaultZone: http://127.0.0.1:10000/eureka/,http://127.0.0.1:10001/eureka/,http://127.0.0.1:10002/eureka/

服務(wù)提供者2:

server:
 port: 8002
spring:
 application:
     name: helloserver

eureka:
 client:
     service-url:
         defaultZone: http://127.0.0.1:10000/eureka/

3. 消費者

3.1 maven引入

<properties>
     <java.version>1.8</java.version>
     <spring-cloud.version>Greenwich.SR1</spring-cloud.version>
 </properties>

 <dependencies>
     <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-actuator</artifactId>
     </dependency>
     <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-web</artifactId>
     </dependency>
     <dependency>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
     </dependency>

     <!-- 重試機制。如果調(diào)用后,出現(xiàn)異常,可以通過重試機制,發(fā)起重試。 -->
     <dependency>
         <groupId>org.springframework.retry</groupId>
         <artifactId>spring-retry</artifactId>
     </dependency>

     <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-test</artifactId>
         <scope>test</scope>
     </dependency>
 </dependencies>

 <dependencyManagement>
     <dependencies>
         <dependency>
             <groupId>org.springframework.cloud</groupId>
             <artifactId>spring-cloud-dependencies</artifactId>
             <version>${spring-cloud.version}</version>
             <type>pom</type>
             <scope>import</scope>
         </dependency>
     </dependencies>
 </dependencyManagement>

 <build>
     <plugins>
         <plugin>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-maven-plugin</artifactId>
         </plugin>
     </plugins>
 </build>

3.2 代碼示例

使用RestTemplate對服務(wù)提供者進行訪問
注:template方法上的 @LoadBalanced 是用來實現(xiàn)負(fù)載均衡,是Ribbon的一種內(nèi)部應(yīng)用模式

/**
* CustomerDemoApplication
*/
@SpringBootApplication
@RestController
public class CustomerDemoApplication {

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

 @Bean
 @LoadBalanced
 public RestTemplate template(){
     return new RestTemplate();
 }

}
/**
* CustomerController
*/
@RestController
public class CustomerController {

 @Autowired
 private RestTemplate restTemplate;

 @GetMapping("index")
 public Object getIndex(){
     //使用RestTemplate對服務(wù)提供者進行訪問,這里使用服務(wù)名去訪問
     return restTemplate.getForObject("http://HELLOSERVER/",String.class,"");
 }

}

3.3 yml配置

server:
 port: 8083

spring:
 application:
     name: consumer-demo

eureka:
 client:
     service-url:
         defaultZone : http://127.0.0.1:10000/eureka/

將Eureka注冊中心、生產(chǎn)者、消費者都啟動起來,可以在頁面上看到注冊的服務(wù)實例:
(注意:Eureka中的instance名稱,不區(qū)分大小寫)

image.png

三、Eureka核心知識

1. 啟動時服務(wù)如何注冊到Eureka的?

image.png

啟動時,通過后臺任務(wù),將 【服務(wù)名、ip、端口】 注冊到EurekaServer

2. 服務(wù)端如何保存這些信息?

image.png

客戶端啟動后,會去調(diào)用http,將服務(wù)實例放在Server內(nèi)部一個Map對象中存儲

3. 消費者如何根據(jù)服務(wù)名稱發(fā)現(xiàn)服務(wù)實例?

image.png

啟動時,通過后臺任務(wù),定期從EurekaServer拉取服務(wù)信息,緩存到消費者本地內(nèi)存中

4. 如何構(gòu)建高可用的eureka集群?

image.png
  • 在高可用狀態(tài)下,Eureka通過【對等協(xié)議】,將注冊在自身的實例,與組內(nèi)其他Eureka進行同步。
  • 在【defaultZone】參數(shù),可配置多個注冊中心的地址。
    以下配置文件中,分別修改 active 屬性值,啟動三個注冊中心。然后啟動生產(chǎn)者,將服務(wù)注冊到其中一個注冊中心。可以看到,三個注冊中心都有注冊的服務(wù)實例
  • 服務(wù)注冊的高可用機制:如果其中一個注冊中心出現(xiàn)問題,不會影響其他注冊中心的處理。
    比如:注冊中心1、2、3之間同步服務(wù)實例。假設(shè)注冊中心1掛了,生產(chǎn)者將服務(wù)注冊到注冊中心 1 ,注冊中心 2 和 3 也還是能收到該生產(chǎn)者注冊的服務(wù)實例
  • 如何防止各注冊中心的重復(fù)傳播:源碼中,通過isReplication判斷
spring:
 profiles:
     active: dev

#分割符號,分割不同的環(huán)境
---
spring:
 application:
     name: eureka-peer
 profiles: dev

server:
 port: 10000

eureka:
 #實例
 instance:
     hostname: dev
     instance-id: dev
 #作為客戶端的配置
 client:
     #是否從eureka拉取信息
     fetch-registry: false
     #是否將自己注冊到eureka
     register-with-eureka: false
     service-url:
         #默認(rèn)的注冊中心的通信地址,高可用配置
         defaultZone: http://localhost:10000/eureka/,http://localhost:10001/eureka/,http://localhost:10002/eureka/
 #作為服務(wù)端的配置
 server:
     #服務(wù)間請求的等待時長
     wait-time-in-ms-when-sync-empty: 0
     #自我保護機制
     enable-self-preservation: true
     #同步時長
     peer-eureka-nodes-update-interval-ms: 10000


---
spring:
 profiles: dev1
 application:
     name: eureka-peer2
server:
 port: 10001


eureka:
 instance:
     hostname: dev1
     instance-id: dev1
 client:
     fetch-registry: false
     register-with-eureka: false
     service-url:
         defaultZone: http://localhost:10000/eureka/,http://localhost:10001/eureka/,http://localhost:10002/eureka/
 server:
     wait-time-in-ms-when-sync-empty: 0
     enable-self-preservation: true
     peer-eureka-nodes-update-interval-ms: 10000
---
spring:
  profiles: dev2
  application:
      name: eureka-peer3
server:
 port: 10002


eureka:
     instance:
         hostname: dev2
         instance-id: dev2
     client:
         fetch-registry: false
         register-with-eureka: false
         service-url:
             defaultZone: http://localhost:10000/eureka/,http://localhost:10001/eureka/,http://localhost:10002/eureka/
     server:
         wait-time-in-ms-when-sync-empty: 0
         enable-self-preservation: true
         peer-eureka-nodes-update-interval-ms: 10000

---

5. 心跳和服務(wù)剔除機制是什么?

image.png

心跳:客戶端定期發(fā)送心跳請求包到EurekaServer
若心跳長時間沒有發(fā)送,eureka則會采用剔除機制,將服務(wù)實例改為 Down 狀態(tài)

6. eureka自我保護模式是什么?

生產(chǎn)上一般會開啟自我保護模式。開啟自我保護機制后,服務(wù)一旦下線,注冊中心中不會剔除該服務(wù),避免將可用的服務(wù)也剔除了。
問題:如何避免調(diào)用到宕機的服務(wù)
處理:提供了補償方案,如重試機制、熔斷機制

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,923評論 6 535
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,740評論 3 420
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,856評論 0 380
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,175評論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 71,931評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,321評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,383評論 3 443
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,533評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,082評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,891評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,067評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,618評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,319評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,732評論 0 27
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,987評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,794評論 3 394
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 48,076評論 2 375

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

  • Eureka是Netflix開發(fā)的服務(wù)發(fā)現(xiàn)框架,本身是一個基于REST的服務(wù),主要用于定位運行在AWS域中的中間層...
    pengyuyancode閱讀 33,023評論 0 18
  • 夜鶯2517閱讀 127,748評論 1 9
  • 版本:ios 1.2.1 亮點: 1.app角標(biāo)可以實時更新天氣溫度或選擇空氣質(zhì)量,建議處女座就不要選了,不然老想...
    我就是沉沉閱讀 6,931評論 1 6
  • 我是一名過去式的高三狗,很可悲,在這三年里我沒有戀愛,看著同齡的小伙伴們一對兒一對兒的,我的心不好受。怎么說呢,高...
    小娘紙閱讀 3,403評論 4 7
  • 我是黑夜里大雨紛飛的人啊 1 “又到一年六月,有人笑有人哭,有人歡樂有人憂愁,有人驚喜有人失落,有的覺得收獲滿滿有...
    陌忘宇閱讀 8,579評論 28 53