1. 程式人生 > >SpringCloud微服務元件—Eureka服務註冊與發現

SpringCloud微服務元件—Eureka服務註冊與發現

前言

本系列文章將簡單的學習SpringCloud微服務相關知識,其實也是因為時間的原因,一直拖到現在,遂打算趁著假期,決定記錄下來。

從天氣預報微服務系統的單體架構——>分散式架構的演變過程中,一步一步,由淺及深的學習SpringCloud微服務的思想與其實現的元件。

本系列文章分為以下幾個章節:

專案原始碼已上傳至Github.

Eureka介紹

Eureka是Spring Cloud Netflix微服務元件中的一部分,是微服務註冊與發現的元件。它本來是Netflix公司的開源專案,後來Spring對其進行了很好的封裝,與SpringCloud無縫整合。

Eureka具有很好的高可用性。Eureka包含了伺服器端和客戶端。
Server端,也被稱作是服務註冊中心,用於提供服務的註冊與發現。Eureka支援高可用的配置,當叢集中有分片出現故障時,Eureka就會轉入自動保護模式,它允許分片故障期間繼續提供服務的發現和註冊,當故障分片恢復正常時,叢集中其他分片會把他們的狀態再次同步回來。
Client端,包含服務消費者與服務生產者。在應用程式執行時,Eureka客戶端向註冊中心註冊自身提供的服務並週期性的傳送心跳來更新它的服務租約。同時也可以從服務端查詢當前註冊的服務資訊並把他們快取到本地並週期性的重新整理服務狀態。
這裡寫圖片描述

專案實戰

Eureka Server

  • 加入依賴
//依賴關係
dependencies {

    //Eureka Server
    compile('org.springframework.cloud:spring-cloud-starter-netflix-eureka-server')

    //該依賴用於測試階段
    testCompile('org.springframework.boot:spring-boot-starter-test')
}

dependencyManagement {
    imports {
            mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
    }
}
  • 加入@EnableEurekaServer註解
@SpringBootApplication
@EnableEurekaServer
public class Application {

    public static void main(String[] args) {

        SpringApplication.run(Application.class, args);
    }
}
  • 配置檔案
server:
  port: 8761

eureka:
  instance:
    hostname: localhost

client:
  register-with-eureka: false
  fetch-registry: false
  service-url:
    defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

server:
  enable-self-preservation: false

Eureka Client

  • 加入依賴
/依賴關係
dependencies {
    //該依賴用於編譯階段
    compile('org.springframework.boot:spring-boot-starter-web')
    //熱部署
    compile('org.springframework.boot:spring-boot-devtools')
    //Eureka Client
    compile('org.springframework.cloud:spring-cloud-starter-netflix-eureka-client')


    //該依賴用於測試階段
    testCompile('org.springframework.boot:spring-boot-starter-test')
}

dependencyManagement {
    imports {
            mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
    }
}
  • 加入@EnableDiscoveryClient註解
@SpringBootApplication
@EnableDiscoveryClient
public class Application {

    public static void main(String[] args) {

        SpringApplication.run(Application.class, args);
    }
}
  • 配置檔案
server:
  port: 9091

spring:
  application:
    name: msa-weather-city-eureka

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/

服務端與客戶端配置完畢之後,訪問8761埠,可以檢視Eureka的預設介面。

這裡寫圖片描述

常用配置引數說明

  • eureka.client.register-with-eureka
    表示是否將自己註冊到Eureka Server,預設為true。
  • eureka.client.fetch-registry
    表示是否從Eureka Server獲取註冊資訊,預設為true。
  • eureka.client.serviceUrl.defaultZone
    設定與Eureka Server互動的地址,查詢服務和註冊服務都需要依賴這個地址。預設是http://localhost:8761/eureka ;多個地址可使用 , 分隔。
  • eureka.instance.lease-expiration-duration-in-seconds
    leaseExpirationDurationInSeconds,表示eureka server至上一次收到client的心跳之後,等待下一次心跳的超時時間,在這個時間內若沒收到下一次心跳,則將移除該instance。預設為90秒,如果該值太大,則很可能將流量轉發過去的時候,該instance已經不存活了。如果該值設定太小了,則instance則很可能因為臨時的網路抖動而被摘除掉。該值至少應該大於leaseRenewalIntervalInSeconds。
  • eureka.instance.lease-renewal-interval-in-seconds
    leaseRenewalIntervalInSeconds,表示eureka client傳送心跳給server端的頻率。如果在leaseExpirationDurationInSeconds後,server端沒有收到client的心跳,則將摘除該instance。除此之外,如果該instance實現了HealthCheckCallback,並決定讓自己unavailable的話,則該instance也不會接收到流量。預設30秒
  • eureka.server.enable-self-preservation
    是否開啟自我保護模式,預設為true。統計一段時間的負載,剔除誤判。
    預設情況下,如果Eureka Server在一定時間內沒有接收到某個微服務例項的心跳,Eureka Server將會登出該例項(預設90秒)。但是當網路分割槽故障發生時,微服務與Eureka Server之間無法正常通訊,以上行為可能變得非常危險了——因為微服務本身其實是健康的,此時本不應該登出這個微服務。
    Eureka通過“自我保護模式”來解決這個問題——當Eureka Server節點在短時間內丟失過多客戶端時(可能發生了網路分割槽故障),那麼這個節點就會進入自我保護模式。一旦進入該模式,Eureka Server就會保護服務登錄檔中的資訊,不再刪除服務登錄檔中的資料(也就是不會登出任何微服務)。當網路故障恢復後,該Eureka Server節點會自動退出自我保護模式。
    綜上,自我保護模式是一種應對網路異常的安全保護措施。它的架構哲學是寧可同時保留所有微服務(健康的微服務和不健康的微服務都會保留),也不盲目登出任何健康的微服務。使用自我保護模式,可以讓Eureka叢集更加的健壯、穩定。
  • eureka.server.eviction-interval-timer-in-ms
    eureka server清理無效節點的時間間隔,預設60000毫秒,即60秒,對於api-gateway,如果要迅速獲取服務註冊狀態,可以縮小該值,比如5秒。

關於叢集

在一個分散式系統中,使用叢集是很常見的。Eureka通過互相註冊的方式來實現高可用的部署,所以我們只需要將Eureke Server配置其他可用Client所指向的serviceUrl就能實現高可用部署。

例如,用mvn對每個微服務專案進行打包,實現幾個可用的服務,註冊在Eureka Server上即可。

java -jar msa-weather-city-eureka-0.0.1-SNAPSHOT.jar --server.port=8081
java -jar msa-weather-city-eureka-0.0.1-SNAPSHOT.jar --server.port=8082

java -jar msa-weather-collection-eureka-feign-0.0.1-SNAPSHOT.jar --server.port=8083
java -jar msa-weather-collection-eureka-feign-0.0.1-SNAPSHOT.jar --server.port=8084

java -jar msa-weather-data-eureka-0.0.1-SNAPSHOT.jar --server.port=8085
java -jar msa-weather-data-eureka-0.0.1-SNAPSHOT.jar --server.port=8086

java -jar msa-weather-report-eureka-feign-gateway-0.0.1-SNAPSHOT.jar --server.port=8087
java -jar msa-weather-report-eureka-feign-gateway-0.0.1-SNAPSHOT.jar --server.port=8088

如果有多個伺服器叢集,可以在yml配置檔案中進行配置,然後使用mvn打包釋出。

---
spring:
  application:
    name: spring-cloud-eureka
  profiles: peer1
server:
  port: 8000
eureka:
  instance:
    hostname: peer1
  client:
    serviceUrl:
      defaultZone: http://peer2:8001/eureka/,http://peer3:8002/eureka/
---
spring:
  application:
    name: spring-cloud-eureka
  profiles: peer2
server:
  port: 8001
eureka:
  instance:
    hostname: peer2
  client:
    serviceUrl:
      defaultZone: http://peer1:8000/eureka/,http://peer3:8002/eureka/
---
spring:
  application:
    name: spring-cloud-eureka
  profiles: peer3
server:
  port: 8002
eureka:
  instance:
    hostname: peer3
  client:
    serviceUrl:
      defaultZone: http://peer1:8000/eureka/,http://peer2:8001/eureka/
java -jar spring-cloud-eureka-0.0.1-SNAPSHOT.jar --spring.profiles.active=peer1
java -jar spring-cloud-eureka-0.0.1-SNAPSHOT.jar --spring.profiles.active=peer2
java -jar spring-cloud-eureka-0.0.1-SNAPSHOT.jar --spring.profiles.active=peer3