1. 程式人生 > 實用技巧 >Eureka服務註冊中心

Eureka服務註冊中心

1. 什麼是Eureka

  • Netflix在涉及Eureka時,遵循的就是API原則.

  • Eureka是Netflix的有個子模組,也是核心模組之一。Eureka是基於REST的服務,用於定位服務,以實現雲端中介軟體層服務發現和故障轉移,服務註冊與發現對於微服務來說是非常重要的,有了服務註冊與發現,只需要使用服務的識別符號,就可以訪問到服務,而不需要修改服務呼叫的配置檔案了,功能類似於Dubbo的註冊中心,比如Zookeeper.

2. 原理理解

  • Eureka基本的架構

    • Springcloud 封裝了Netflix公司開發的Eureka模組來實現服務註冊與發現 (對比Zookeeper).

    • Eureka採用了C-S的架構設計,EurekaServer作為服務註冊功能的伺服器,他是服務註冊中心.

    • 而系統中的其他微服務,使用Eureka的客戶端連線到EurekaServer並維持心跳連線。這樣系統的維護人員就可以通過EurekaServer來監控系統中各個微服務是否正常執行,Springcloud 的一些其他模組 (比如Zuul) 就可以通過EurekaServer來發現系統中的其他微服務,並執行相關的邏輯.

就是消費者和提供者都會連線這個註冊中心,來維持一個心跳這個東西,沒有心跳了,就說明你死掉了。

  • 和Dubbo架構對比.

  • Eureka 包含兩個元件:Eureka Server

    Eureka Client.

  • Eureka Server 提供服務註冊,各個節點啟動後,回在EurekaServer中進行註冊,這樣Eureka Server中的服務登錄檔中將會儲存所有課用服務節點的資訊,服務節點的資訊可以在介面中直觀的看到.

  • Eureka Client 是一個Java客戶端,用於簡化EurekaServer的互動,客戶端同時也具備一個內建的,使用輪詢負載演算法的負載均衡器。在應用啟動後,將會向EurekaServer傳送心跳 (預設週期為30秒) 。如果Eureka Server在多個心跳週期內沒有接收到某個節點的心跳,EurekaServer將會從服務登錄檔中把這個服務節點移除掉 (預設週期為90s).

  • 三大角色

    • Eureka Server:提供服務的註冊與發現

    • Service Provider:服務生產方,將自身服務註冊到Eureka中,從而使服務消費方能狗找到

    • Service Consumer:服務消費方,從Eureka中獲取註冊服務列表,從而找到消費服務

3. 改寫我們之前寫的Rest程式

3.1 新建第四個模組

3.2 匯入依賴

<dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-eureka-server</artifactId>
        <version>1.4.6.RELEASE</version>
    </dependency>
    <!--熱部署工具-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
    </dependency>

  

3.3 建立application.yml並編寫

server:
  port: 7001
#Eureka配置
eureka:
  instance:
    hostname: localhost #Eureka服務端的例項名稱
  client:
    register-with-eureka: false #表示是否像註冊中心Eureka註冊自己
    fetch-registry: false # 如果為false,就表示自己是註冊中心
    service-url: #監控頁面
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

  

3.4 編寫主啟動類

package com.yao.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
@EnableEurekaServer //服務端的啟動類,可以接受別人註冊進來~
public class EurekaServer_7001 {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServer_7001.class,args);
    }
}

  

3.5 啟動測試主啟動類(如下就是它註冊中心的預設頁面)

4 回到8001那個埠,也就是服務提供者

4.1 像pom.xml中新增Eureka的依賴

<!--Eureka依賴-->
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka</artifactId>
    <version>1.4.6.RELEASE</version>
</dependency>

  

4.2 在application.yml新增Eureka相關的配置

# Eureka配置:配置服務註冊中心地址
eureka:
  client:
    service-url:
      defaultZone: http://localhost:7001/eureka/

  

4.3 主啟動類加一個註解

@EnableEurekaClient
package com.yao.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

//啟動類
@SpringBootApplication
@EnableEurekaClient //在服務啟動後自動註冊到Eureka中
public class DeptProvider_8001 {
    public static void main(String[] args) {
        SpringApplication.run(DeptProvider_8001.class,args);
    }
}

  

4.4 啟動註冊,先啟動註冊中心也就是7001,再啟動服務端8001

  1. 修改Eureka上的預設描述資訊

    # Eureka配置:配置服務註冊中心地址
    eureka:
    client:
    service-url:
    defaultZone: http://localhost:7001/eureka/
    instance:
    instance-id: springcloud-provider-dept-8001 #修改Eureka上的預設描述資訊
    1234567

    結果如圖(可以看到status顯示的資訊被修改了):

    如果此時停掉springcloud-provider-dept-8001 等30s後 監控會開啟保護機制:

    1. 配置關於服務載入的監控資訊(這個Status對應著下面一個連結,我們可以去修改這個連結)

4.5 完善監控資訊

<!--actuator完善監控資訊-->
<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

  

4.6 application.yml中新增配置

# info配置
info:
# 專案的名稱
app.name: haust-springcloud
# 公司的名稱
company.name: 么么

  

4.7 重新啟動7001和8001測試

點開是這樣的,可以告訴別人這個微服務的相關資訊

4.8. 說明一下剛剛自我Eureka保護機制,監控頁面報紅的原因

EureKa自我保護機制:好死不如賴活著

一句話總結就是:某時刻某一個微服務不可用,eureka不會立即清理,依舊會對該微服務的資訊進行儲存!

  • 預設情況下,當eureka server在一定時間內沒有收到例項的心跳,便會把該例項從登錄檔中刪除(預設是90秒),但是,如果短時間內丟失大量的例項心跳,便會觸發eureka server的自我保護機制,比如在開發測試時,需要頻繁地重啟微服務例項,但是我們很少會把eureka server一起重啟(因為在開發過程中不會修改eureka註冊中心),當一分鐘內收到的心跳數大量減少時,會觸發該保護機制。可以在eureka管理介面看到Renews threshold和Renews(last min),當後者(最後一分鐘收到的心跳數)小於前者(心跳閾值)的時候,觸發保護機制,會出現紅色的警告:EMERGENCY!EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY'RE NOT.RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEGING EXPIRED JUST TO BE SAFE.從警告中可以看到,eureka認為雖然收不到例項的心跳,但它認為例項還是健康的,eureka會保護這些例項,不會把它們從登錄檔中刪掉。

  • 該保護機制的目的是避免網路連線故障,在發生網路故障時,微服務和註冊中心之間無法正常通訊,但服務本身是健康的,不應該登出該服務,如果eureka因網路故障而把微服務誤刪了,那即使網路恢復了,該微服務也不會重新註冊到eureka server了,因為只有在微服務啟動的時候才會發起註冊請求,後面只會傳送心跳和服務列表請求,這樣的話,該例項雖然是執行著,但永遠不會被其它服務所感知。所以,eureka server在短時間內丟失過多的客戶端心跳時,會進入自我保護模式,該模式下,eureka會保護登錄檔中的資訊,不在登出任何微服務,當網路故障恢復後,eureka會自動退出保護模式。自我保護模式可以讓叢集更加健壯。

  • 但是我們在開發測試階段,需要頻繁地重啟發布,如果觸發了保護機制,則舊的服務例項沒有被刪除,這時請求有可能跑到舊的例項中,而該例項已經關閉了,這就導致請求錯誤,影響開發測試。所以,在開發測試階段,我們可以把自我保護模式關閉,只需在eureka server配置檔案中加上如下配置即可:eureka.server.enable-self-preservation=false【不推薦關閉自我保護機制】

詳細內容可以參考下這篇部落格內容:https://blog.csdn.net/wudiyong22/article/details/80827594

4.9 註冊進來的微服務,獲取一些訊息(團隊開發會用到)

4.9.1在controller層中的DeptController.java新增方法

/**
 * DiscoveryClient 可以用來獲取一些配置的資訊,得到具體的微服務!
 */
@Autowired
private DiscoveryClient client;
​
/**
 * 獲取一些註冊進來的微服務的資訊~,
 *
 * @return
 */
@GetMapping("/dept/discovery")
public Object discovery() {
    // 獲取微服務列表的清單
    List<String> services = client.getServices();
    System.out.println("discovery=>services:" + services);
    // 得到一個具體的微服務資訊,通過具體的微服務id,applicaioinName;
    List<ServiceInstance> instances = client.getInstances("SPRINGCLOUD-PROVIDER-DEPT");
    for (ServiceInstance instance : instances) {
        System.out.println(
                instance.getHost() + "\t" + // 主機名稱
                        instance.getPort() + "\t" + // 埠號
                        instance.getUri() + "\t" + // uri
                        instance.getServiceId() // 服務id
        );
    }
    return this.client;
}

  

4.9.2 在主啟動類中去新增一個註解

package com.yao.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

//啟動類
@SpringBootApplication
@EnableEurekaClient //在服務啟動後自動註冊到Eureka中
@EnableDiscoveryClient//服務發現
public class DeptProvider_8001 {
    public static void main(String[] args) {
        SpringApplication.run(DeptProvider_8001.class,args);
    }
}

  

5. 重新啟動8001埠測試

也就是訪問我們剛剛也得controller就可以看到一些微服務相關的資訊

同時控制檯也獲取了資訊:

6. 叢集環境配置

6.1 建立兩個新的eureka模組

6.2 匯入相關依賴

<!--導包~-->
<dependencies>
    <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka-server -->
    <!--匯入Eureka Server依賴-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-eureka-server</artifactId>
        <version>1.4.6.RELEASE</version>
    </dependency>
    <!--熱部署工具-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
    </dependency>
</dependencies>

  

6.3 匯入我們剛剛在springcloud-eureka-7001中寫的application.yml直接copy過來就可以了,但是記得把埠號改一下

如下:

server:
  port: 7002
#Eureka配置
eureka:
  instance:
    hostname: localhost #Eureka服務端的例項名稱
  client:
    register-with-eureka: false #表示是否像註冊中心Eureka註冊自己
    fetch-registry: false # 如果為false,就表示自己是註冊中心
    service-url: #監控頁面
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

  

server:
  port: 7003
#Eureka配置
eureka:
  instance:
    hostname: localhost #Eureka服務端的例項名稱
  client:
    register-with-eureka: false #表示是否像註冊中心Eureka註冊自己
    fetch-registry: false # 如果為false,就表示自己是註冊中心
    service-url: #監控頁面
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

  

6.4 匯入我們剛剛在springcloud-eureka-7001中寫的主啟動類直接copy java資料夾過來就可以了,但是記得把名字改一下。

如下:

package java.com.yao.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
@EnableEurekaServer //服務端的啟動類,可以接受別人註冊進來~
public class EurekaServer_7002 {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServer_7002.class,args);
    }
}

  

package java.com.yao.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
@EnableEurekaServer //服務端的啟動類,可以接受別人註冊進來~
public class EurekaServer_7003 {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServer_7003.class,args);
    }
}

  

6.5叢集成員相互關聯

為了我們可以很好的模擬三個eureka的區別,我們設定一下他們三個訪問的url,就是我們一般都用localhost也就是127.0.0.1 ,將這個東西替換成我們自定義的。

找到這個文字檔案:

更改如下(加上這幾條就可以了):

注意這裡把屬性中只讀去掉和加入寫入,修改才可以儲存,注意這裡要選到users那裡

6.5.1 修改7001,7002,7003三個註冊中心中的application.yml檔案來實現三個註冊中心兩兩關聯來達到一個叢集的作用

7001的application.yml:

server:
  port: 7001
#Eureka配置
eureka:
  instance:
    hostname: eureka7001.com #Eureka服務端的例項名稱
  client:
    register-with-eureka: false #表示是否像註冊中心Eureka註冊自己
    fetch-registry: false # 如果為false,就表示自己是註冊中心
    service-url: #監控頁面
      # 單機:http://${eureka.instance.hostname}:${server.port}/eureka/
      #叢集:
      defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/

  

7002的application.yml:

server:
  port: 7002
#Eureka配置
eureka:
  instance:
    hostname: eureka7001.com #Eureka服務端的例項名稱
  client:
    register-with-eureka: false #表示是否像註冊中心Eureka註冊自己
    fetch-registry: false # 如果為false,就表示自己是註冊中心
    service-url: #監控頁面
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7003.com:7003/eureka/

  

7003的application.yml:

server:
  port: 7003
#Eureka配置
eureka:
  instance:
    hostname: eureka7003.com #Eureka服務端的例項名稱
  client:
    register-with-eureka: false #表示是否像註冊中心Eureka註冊自己
    fetch-registry: false # 如果為false,就表示自己是註冊中心
    service-url: #監控頁面
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7003.com:7003/eureka/

  

6.5.2 修改8001埠,也就是伺服器端中的配置檔案,使服務註冊不再是向一個單一的註冊中心,而是向一個叢集去釋出

server:
  port: 8001

#mybatis配置
mybatis:
  type-aliases-package: com.yao.springcloud.pojo
  config-location: classpath:mybatis/mybatis-config.xml
  mapper-locations: classpath:mybatis/mapper/*.xml

#spring配置
spring:
  application:
    name: springcloud-provider-dept
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: org.gjt.mm.mysql.Driver
    url: jdbc:mysql://localhost:3306/db01?useUnicode=true&characterEncoding=utf-8
    username: root
    password: 892095368llq

# Eureka配置:配置服務註冊中心地址
eureka:
  client:
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
  instance:
    instance-id: springcloud-provider-dept8001
# info配置
info:
# 專案的名稱
  app.name: haust-springcloud
# 公司的名稱
  company.name: 么么

  

這樣模擬叢集就搭建號了,就可以把一個專案掛載到三個伺服器上了

7. 測試 依次啟動7001,7002,7003和

package java.com.yao.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
@EnableEurekaServer //服務端的啟動類,可以接受別人註冊進來~
public class EurekaServer_7003 {
public static void main(String[] args) {
SpringApplication.run(EurekaServer_7003.class,args);
}
}