【成爲博客專家】一篇文章學會SpringCloud Eureka

My Name is YangYang

Eureka簡介

在微服務架構中往往會有一個註冊中心,每個微服務都會向註冊中心去註冊自己的地址及端口信息,註冊中心維護着服務名稱與服務實例的對應關係。每個微服務都會定時從註冊中心獲取服務列表,同時彙報自己的運行情況,這樣當有的服務需要調用其他服務時,就可以從自己獲取到的服務列表中獲取實例地址進行調用,Eureka實現了這套服務註冊與發現機制。

搭建Eureka註冊中心

使用IDEA來創建SpringCloud應用

Eureka分爲註冊和發現,所以需要創建Server模塊和Client模塊,簡單些講實際項目中Eureka作爲註冊Server模塊,其他子服務屬於Client模塊。

  • 創建一個eureka-server模塊,並使用Spring Initializer初始化一個SpringBoot項目
    在這裏插入圖片描述
  • 填寫應用信息
    在這裏插入圖片描述
  • 選擇你需要的SpringCloud組件進行創建
    在這裏插入圖片描述
  • 添加Pom.xml依賴
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
  • 在啓動類上添加@EnableEurekaServer註解來啓用Euerka註冊中心功能

@EnableEurekaServer
@SpringBootApplication
public class EurekaServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class, args);
    }
}
  • 在配置文件application.yml中添加Eureka註冊中心的配置
server:
  port: 8001 #指定運行端口
spring:
  application:
    name: eureka-server #指定服務名稱
eureka:
  instance:
    hostname: localhost #指定主機地址
  client:
    fetch-registry: false #指定是否要從註冊中心獲取服務(註冊中心不需要開啓)
    register-with-eureka: false #指定是否要註冊到註冊中心(註冊中心不需要開啓)
  server:
    enable-self-preservation: false #關閉保護模式

使用IDEA的Run Dashboard來運行SpringCloud應用

  • 打開Run Dashboard,默認情況下,當IDEA檢查到你的項目中有SpringBoot應用時,會提示你開啓,如果你沒開啓,可以用以下方法開啓。
    在這裏插入圖片描述
  • 運行SpringCloud應用
    運行模塊
  • 運行完成後訪問地址 http://localhost:8001/ 可以看到Eureka註冊中心的界面
    在這裏插入圖片描述

搭建Eureka客戶端

  • 新建一個eureka-client模塊,並在pom.xml中添加如下依賴
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
  • 在啓動類上添加@EnableDiscoveryClient註解表明是一個Eureka客戶端
@EnableDiscoveryClient
@SpringBootApplication
public class EurekaClientApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaClientApplication.class, args);
    }
}
  • 在配置文件application.yml中添加Eureka客戶端的配置
server:
  port: 8101 #運行端口號
spring:
  application:
    name: eureka-client #服務名稱
eureka:
  client:
    register-with-eureka: true #註冊到Eureka的註冊中心
    fetch-registry: true #獲取註冊實例列表
    service-url:
      defaultZone: http://localhost:8001/eureka/ #配置註冊中心地址

在這裏插入圖片描述

Eureka原理圖

在這裏插入圖片描述

  • 庫存服務註冊原理圖
    在這裏插入圖片描述
    在這裏插入圖片描述

  • eureka底層實現是使用concurrentHashMap,圖中爲eureka的實現原理可以很清楚的理解,其中有個多級緩存,服務每隔30s發送一個心跳。

  • 註冊到服務註冊中心,接着立馬同步到readwith緩存中,接着30s同步到readonly緩存中,然後服務每隔30s拉取註冊表即可調用註冊中的服務。

  • 服務下線是在eureka中有個每隔60s的定時檢查,然後從readwith中剔除,30s後再從readonly中剔除,再會去被拉取。

  • 從中可以看出時間還是比較長的,當在生產環境中還是要優化一下的,服務的發現還是比較慢的。

  • 服務的實例是如何從服務中心剔除的:eureka server 要求client端定時進行續約,也就是發送心跳,來證明該服務實例還存活,是健康的,是可以調用的。

  • 如果租約超過一定的時間沒有進行續約操作,eureka server端會主動的剔除,這一點即心跳模式。

Eureka參數含義

配置 含義 默認值
eureka.client.enabled 是否啓用Eureka Client 默認值:true true
eureka.client.register-with-eureka 表示是否將自己註冊到Eureka Server 默認值:true true
eureka.client.fetch-registry 表示是否從Eureka Server獲取註冊的服務信息默認值:true true
eureka.client.serviceUrl.defaultZone 配置Eureka Server地址,用於註冊服務和獲取服務默認值:http://localhost:8761/eureka http://localhost:8761/eureka
eureka.client.registry-fetch-interval-seconds 默認值爲30秒,即每30秒去Eureka Server上獲取服務並緩存默認值:30 30
eureka.instance.lease-renewal-interval-in-seconds 向Eureka Server發送心跳的間隔時間,單位爲秒,用於服務續約默認值:30 30
eureka.instance.lease-expiration-duration-in-seconds 定義服務失效時間,即Eureka Server檢測到Eureka Client木有心跳後(客戶端意外下線)多少秒將其剔除默認值:90 90
eureka.server.enable-self-preservation 用於開啓Eureka Server自我保護功能默認值:true true
eureka.client.instance-info-replication-interval-seconds 更新實例信息的變化到Eureka服務端的間隔時間,單位爲秒默認值:30 30
eureka.client.eureka-service-url-poll-interval-seconds 輪詢Eureka服務端地址更改的間隔時間,單位爲秒。默認值:300 300
eureka.instance.prefer-ip-address 表示使用IP進行配置爲不是域名默認值:false false
eureka.client.healthcheck.enabled 默認Erueka Server是通過心跳來檢測Eureka Client的健康狀況的,通過置爲true改變Eeureka Server對客戶端健康檢測的方式,改用Actuator的/health端點來檢測。默認值:false false

Eureka常用配置

eureka:
  server:
    wait-time-in-ms-when-sync-empty: 0   #在eureka服務器獲取不到集羣裏對等服務器上的實例時,需要等待的時間,單機默認0
    shouldUseReadOnlyResponseCache: true #eureka是CAP理論種基於AP策略,爲了保證強一致性關閉此切換CP 默認不關閉 false關閉
    enable-self-preservation: false    #關閉服務器自我保護,客戶端心跳檢測15分鐘內錯誤達到80%服務會保護,導致別人還認爲是好用的服務
    eviction-interval-timer-in-ms: 6000 #清理間隔(單位毫秒,默認是60*1000)5秒將客戶端剔除的服務在服務註冊列表中剔除#
    response-cache-update-interval-ms: 3000  #eureka server刷新readCacheMap的時間,注意,client讀取的是readCacheMap,這個時間決定了多久會把readWriteCacheMap的緩存更新到readCacheMap上 #eureka server刷新readCacheMap的時間,注意,client讀取的是readCacheMap,這個時間決定了多久會把readWriteCacheMap的緩存更新到readCacheMap上默認30s
    response-cache-auto-expiration-in-seconds: 180   #eureka server緩存readWriteCacheMap失效時間,這個只有在這個時間過去後緩存纔會失效,失效前不會更新,過期後從registry重新讀取註冊服務信息,registry是一個ConcurrentHashMap。
  instance:
    prefer-ip-address: true
    instance-id: ${spring.application.name}:${spring.cloud.client.ip-address}:${spring.application.instance_id:${server.port}}
    hostname: 127.0.0.1
    lease-renewal-interval-in-seconds: 30    # 續約更新時間間隔(默認30秒),eureka客戶端向服務端發送心跳的時間間隔
    lease-expiration-duration-in-seconds: 90 # 續約到期時間(默認90秒)
  client:
    #註冊到其他eureka
    registerWithEureka: false
    fetchRegistry: false #爲true時,可以啓動,但報異常:Cannot execute request on any known server ,是否從eureka服務端獲取註冊信息,消費者需要配置true
    register-with-eureka: false  #表示是否將服務註冊到Eureka服務端,由於自身就是Eureka服務端,所以設置爲false;
    fetch-registry: false #表示是否從Eureka服務端獲取服務信息,因爲這裏只搭建了一個Eureka服務端,並不需要從別的Eureka服務端同步服務信息,所以這裏設置爲false;
    instance-info-replication-interval-seconds: 10  #更新實例信息的變化到Eureka服務端的間隔時間,單位爲秒
    registry-fetch-interval-seconds: 30  #從eureka服務端獲取註冊信息的間隔時間
    eureka-service-url-poll-interval-seconds: 300 #輪詢Eureka服務端地址更改的間隔時間,單位爲秒。
    service-url:
      defaultZone: http://lee:lee@${eureka.instance.hostname}:${server.port}/eureka/

Eureka必須優化參數

eureka.server.responseCacheUpdateIntervalMs = 3000 #eureka server刷新readCacheMap的時間,注意,client讀取的是readCacheMap,這個時間決定了多久會把readWriteCacheMap的緩存更新到readCacheMap上 默認30s
eureka.client.registryFetchIntervalSeconds = 30000 #從eureka服務端獲取註冊信息的間隔時間
eureka.client.leaseRenewalIntervalInSeconds = 30 # 續約更新時間間隔(默認30秒),eureka客戶端向服務端發送心跳的時間間隔
eureka.server.evictionIntervalTimerInMs = 60000 #清理間隔(單位毫秒,默認是60*1000)5秒將客戶端剔除的服務在服務註冊列表中剔除#
eureka.instance.leaseExpirationDurationInSeconds = 90 90 # 續約到期時間(默認90秒)
  • 服務發現的時效性變成秒級,幾秒鐘可以感知服務的上線和下線 這樣eurek server差不多就優化好了,我們再優化下client端。
spring:
  application:
    name: api-gateway
  cloud:
    config:
      discovery:
        enabled: true
        service-id: CONFIG
      profile: dev
eureka:
  client:
    service-url:
      defaultZone: http://lee:[email protected]:8080/eureka
    registry-fetch-interval-seconds: 5 #eureka client刷新本地緩存時間,默認30
  instance:
    hostname: 127.0.0.1
    instance-id: 127.0.0.1:9000
    lease-expiration-duration-in-seconds: 7  #Eureka服務端在收到最後一次心跳之後等待的時間上限,單位爲秒,超過則剔除(客戶端告訴服務端按照此規則等待自己),默認90
    lease-renewal-interval-in-seconds: 5   #Eureka客戶端向服務端發送心跳的時間間隔,單位爲秒(客戶端告訴服務端自己會按照該規則),默認30

Eureka與Zookeeper的區別

CAP,C是一致性,A是可用性,P是分區容錯性。

  • zk是有一個leader節點會接受數據,然後同步到其他的節點,一但leader掛了,要重新選舉leader,這個過程爲了保證C,就犧牲了A,不接用一段時間,但是一個leader選舉好了,就可以繼續寫數據了,保證一致性,即CP

  • eureka是peer模式,可能還沒同步數據過去,結果自己就死了,此時還是可以繼續從別的eureka機器上拉取註冊表,但是可能看到的就不是最新的數據了,但是保證了可用性A,即AP。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章