springcloud-Eureka組件

1、簡介

Eureka 是 Netflix 開發的服務發現框架,自己是一個基於 REST 的服務,主要用於定位運行在 AWS 域中的中間層服務,以達到負載均衡和中間層服務故障轉移的目的。SpringCloud 將它集成在其子項目 spring-cloud-netflix 中,以實現 SpringCloud 的服務發現功能。java

2、組成

Eureka 包含兩個部分,EurekaServer 和 EurekaClient。程序員

  • EurekaServer 是註冊中心,負責微服務的發現功能,各個 EurekaClient 啓動後也會註冊到配置的 EurekaServer 中,Eureka Server 經過 Register、Get、Renew 等接口提供服務的註冊、發現和心跳檢測等服務,各個 EurekaServer 也是一個服務,能夠在集羣版中註冊到其餘的 EurekaServer 中,保證高可用。
  • EurekaClient 是各個 java 微服務應用,在應用啓動後向 EurekaServer 註冊,並週期性的向 Eureka Server 發送心跳,默認週期爲 30 秒,若是 Eureka Server 在多個心跳週期內沒有接收到某個節點的心跳,Eureka Server 將會從服務註冊表中把這個服務節點移除,默認 90 秒,服務提供方和服務消費方統一都屬於 EurekaClient。

3、架構原理

Eureka架構圖.png

  • Register(服務註冊):把本身的 IP 和端口註冊給 EurekaServer。
  • Renew(服務續約):發送心跳包,每 30 秒發送一次。告訴 EurekaServer 本身還活着。
  • Cancel(服務下線):當 provider 關閉時會向 EurekaServer 發送消息,把本身從服務列表中刪除。防止 consumer 調用到不存在的服務。
  • Get Registry(獲取服務註冊列表):獲取其餘服務列表。
  • Replicate(集羣中數據同步):eurekaServer 集羣中的數據複製與同步。
  • Make Remote Call(遠程調用):完成服務的遠程調用。

4、構建單機版 EurekaServer

1)首先在 pom.xml 文件引入須要用到的依賴包,以下:算法

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.16.RELEASE</version>
  </parent>

  <groupId>com.aizen</groupId>
  <artifactId>springcloud-eureka-test</artifactId>
  <version>1.0-SNAPSHOT</version>
  <name>springcloud-eureka-test</name>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>

  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-dependencies</artifactId>
        <version>Edgware.SR4</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>

  <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>
    <!-- spring cloud Eureka Server 啓動器,健康檢查及安全認證會用到 -->
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-eureka-server</artifactId>
    </dependency>
    <!-- spring 監控組件 -->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-actuator</artifactId>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
    <resources>
      <resource>
        <filtering>true</filtering>
        <directory>src/main/resources</directory>
      </resource>
    </resources>
  </build>
</project>

2)而後在 application.yml 文件中配置完成基本功能經常使用的基本項:spring

server:
  port: 8080
spring:
  application:
    name: eureka-server
eureka:
  instance:
    # 獲取當前節點的ip地址
    hostname: ${spring.cloud.client.ipAddress}
    # 表示eureka server至上一次收到client的心跳以後,等待下一次心跳的超時時間,在這個時間內若沒收到下一次心跳,則將移除該instance
    lease-expiration-duration-in-seconds: 90
    # 表示eureka client發送心跳給server端的頻率
    lease-renewal-interval-in-seconds: 30
    prefer-ip-address: true
    instance-id: ${spring.cloud.client.ipAddress}:${server.port}
  server:
    # 服務保護模式(自我保護模式):通常狀況下,微服務在Eureka上註冊後,會每30秒發送心跳包,Eureka經過心跳來判斷服務時候健康,
    # 同時會按期刪除超過90秒沒有發送心跳服務。
    # 致使Eureka Server接收不到心跳包的可能:一是微服務自身的緣由,二是微服務與Eureka之間的網絡故障。
    # 一般微服務的自身的故障只會致使個別服務出現故障,通常不會出現大面積故障,而網絡故障一般會致使Eureka Server在短期內沒法收到大批心跳。
    # 慮到這個區別,Eureka設置了一個閥值,當判斷掛掉的服務的數量超過閥值時,Eureka Server認爲很大程度上出現了網絡故障,將再也不刪除心跳過時的服務。
    # Eureka Server在運行期間,會統計心跳失敗的比例在15分鐘內是否低於85%,若是低於85%,Eureka Server則任務是網絡故障,不會刪除心跳過時服務。
    # 這種服務保護算法叫作Eureka Server的服務保護模式。
    # 這種不刪除的,90秒沒有心跳的服務,稱爲無效服務,可是仍是保存在服務列表中。若是Consumer到註冊中心發現服務,
    # 則Eureka Server會將全部好的數據(有效服務數據)和壞的數據(無效服務數據)都返回給Consumer。
    enable-self-preservation: false
    # eureka server清理無效節點的時間間隔,默認60000毫秒,即60秒
    eviction-interval-timer-in-ms: 60000
  client:
    # 是否將本身做爲微服務註冊到 Eureka-Serve r中,默認的爲true
    register-with-eureka: false
    # 是否從 Eureka-Server 中獲取服務註冊信息,默認爲true,單機版設置爲 false,集羣版設置爲 true,多個 Eureka-Server 互相同步數據
    fetch-registry: false
    # 設置服務註冊中心地址,查詢服務和註冊服務都須要依賴這個地址
    service-url:
      default-zone: http://${eureka.instance.instance-id}/eureka/
    # 從eureka服務器註冊表中獲取註冊信息的時間間隔,對於api-gateway,若是要迅速獲取服務註冊狀態,能夠縮小該值,好比5秒
    registry-fetch-interval-seconds: 30
    # 開啓健康檢查(依賴spring-boot-starter-actuator)
    healthcheck:
      enabled: true
  • 關於 EurekaClient 的詳細配置 能夠在查看如下文件:~/.m2/repository/org/springframework/cloud/spring-cloud-netflix-eureka-client/1.2.3.RELEASE/spring-cloud-netflix-eureka-client-1.2.3.RELEASE.jar!/META-INF/spring-configuration-metadata.json
  • 關於 EurekaServer 的詳細配置 能夠在查看如下文件:~/.m2/repository/org/springframework/cloud/spring-cloud-netflix-eureka-server/1.2.3.RELEASE/spring-cloud-netflix-eureka-server-1.2.3.RELEASE.jar!/META-INF/spring-configuration-metadata.json

3)最後啓動類配置:apache

@EnableEurekaServer
@SpringBootApplication(scanBasePackages = {"com.test"})
public class EurekaTestApplication {
    public static void main(String[] args){
        SpringApplication.run(EurekaTestApplication.class, args);
    }
}

啓動程序,訪問 http://localhost:8080 便可查看 eurekaServer 基本信息。json

5、搭建集羣版 EurekaServer

Eureka 做爲微服務的註冊中心,在微服務生態中是極其重要的角色,單機版的 eureka 並不能保證註冊中心的高可用性,因此在商用時通常都配置集羣版的 Eureka 集羣。api

集羣版的 pom 依賴和啓動類同單機版;
application.yml 配置文件中有一點不一樣,設置註冊中心時,將本節點註冊到其餘全部的集羣節點中:緩存

eureka:
  client:
    # 設置服務註冊中心地址,配置多個 eurekaServer 的 host
    service-url:
      default-zone: http://192.168.0.2/eureka/,http://192.168.0.3/eureka/

EurekaServer 的每一個節點都是平等的,每一個節點都向外提供服務發現和註冊功能,能夠做爲微服務註冊到其餘 EurekaServer 節點並發現其餘節點中已註冊的服務。所以不少程序員會將不一樣的微服務註冊到不一樣的 EurekaServer 節點,而後經過 EurekaServer 節點之間相互註冊通信來發現所有的微服務,這種方法是極不推薦的,由於 EurekaServer 在服務管理上,會根據連帶責任來維護註冊的服務列表,若是某臺 EurekaServer 節點宕機,則該節點中註冊的全部微服務都會被刪除,所以,推薦 EurekaClient 配置註冊中心時配置 EurekaServer 中全部節點。安全

6、關於 EurekaServer 的自我保護模式

1. 自我保護模式

默認狀況下,微服務會定時(默認30秒,可自行配置)向 EurekaServer 發送心跳,若是必定時間內(默認90秒,可自行配置)EurekaServer 沒有收到某個微服務的心跳,則會從微服務列表中剔除該微服務,這是正常的微服務治理機制。服務器

但在微服務自己健康狀況下,可能會因爲網絡緣由沒法與 EurekaServer 通訊,此時不該該錯誤的剔除掉該微服務,Eureka 爲了解決該問題提出 自我保護模式

Eureka Server 在運行期間會去統計節點心跳失敗比例在 15 分鐘以內是否低於 85%,若是低於 85%,Eureka Server 會認爲發生了網絡故障,不會從列表中刪除這些心跳過時的服務,這些服務稱爲無效服務。此時若是 Consumer 從註冊中心發現服務,註冊中心會將有效服務和無效服務一塊兒返回,Consumer 調用了無效服務就會失敗,這裏須要 Consumer 使用熔斷器來提供容錯處理以提高系統穩定性和用戶體驗。

2. 自我保護激活條件

在 1 分鐘後 Renews (last min) < Renews threshold

  • Renews : Eureka Server 指望每分鐘收到客戶端實例續約的總數。計算公式以下:

    當前服務節點數 * (60s/心跳間隔) * 0.85 #默認心跳間隔30s,默認心跳失敗比例 0.85,均可經過配置文件更改

  • Renews threshold:Eureka Server 最後 1 分鐘實際收到客戶端實例續約的總數。
    這兩個參數能夠在 Eureka 信息頁面看到:
    Eureka 信息頁面.png

3. Eureka 開啓健康檢查

在上圖中,Status 欄顯示着 UP,表示應用程序狀態正常。其它取值 DOWN、OUT_OF_SERVICE、UNKNOWN 等,只有 UP 的微服務會被請求。

因爲 EurekaServer 與 EurekaClient 經過心跳機制來判斷應用程序狀態,所以只要二者之間的心跳保持正常,應用程序狀態就會一直保持 UP 狀態,因此 Status 值並不能徹底反應應用的實際健康狀態。

咱們可使用 Spring Boot Actuator 的健康檢查機制來完成應用程序的健康檢查,並將節點的健康狀態傳播給 EurekaServer,配置文件以下:

eureka:
  client:
    # 開啓健康檢查(依賴spring-boot-starter-actuator)
    healthcheck:
      enabled: true

若是須要更細粒度健康檢查,可實現 com.netflix.appinfo.HealthCheckHandler 接口,EurekaHealthCheckHandler 已實現了該接口。

4. 自我保護模式的優缺點

  • 優勢:

    1. 保留無效服務能夠防止誤刪除健康服務,待網絡故障消除,EurekaServer 會自動退出自我保護模式;
    2. EurekaClient 具備緩存服務列表功能,即便 EurekaServer 出現網絡故障,Consumer 和 Provider 之間也能夠正常通訊,只有全部的 Provider 都不可用時,Consumer 纔會從註冊中心從新發現服務列表;
    3. 微服務的負載均衡策略會自動剔除死亡的微服務節點(Robbin)。
  • 缺點:

    1. 當無效服務中包括不健康 Provider 節點時,Consumer 發現服務列表後,請求 Provoder 會調用失敗,此時須要額外使用熔斷器來增強容錯。

單機版可關閉自我保護:

eureka:
  server:
    enable-self-preservation: false

7、EurekaClient

EurekaClient 在配置註冊中心時,建議把全部的 EurekaServer 集羣全部節點都配置上。 實際上,只配置一個 Eureka Server 節點其實就能夠了,可是,Eureka Server 對服務的管理有連帶責任。若是隻配置一個Eureka Server 節點,那麼會致使連帶刪除的風險,致使服務不可靠。若是配置了多個 Eureka Server 節點,EurekaClient 在註冊服務時會根據註冊中心列表順序註冊,不會將當前的服務同時註冊到全部 Eureka Server 節點上,從第一個配置的 Eureka Server節 點開始註冊,若是註冊成功,後續的 Eureka Server 節點再也不重複註冊,每30秒,Eureka Client 發送一個心跳到 Eureka Server 上,若是心跳沒有反饋,則從已配置的 Eureka Server 節點列表的下一個服務節點繼續註冊。這樣作能夠保證服務的可靠性,下降服務連帶責任致使的服務不可靠。

當有多個 EurekaClient 須要註冊時,建議 EurekaServer 的順序異序排列,即微服務A註冊中心服務順序爲 s1,s2,s3,微服務B推薦爲 s2,s3,s1……這樣能夠充分發揮 EurekaServer 集羣的特性,由於 Eureka Server 和 Eureka Client 對心跳的監測都是(3*間隔時間)的,因此會有服務列表數據的不一樣步可能。在CAP原則上,Eureka Server是保證AP原則,放棄C原則的。
1)基本的 application.yaml 配置:

spring:
  application:
    name: user-service
server:
  port: 8080

# 配置Eureka Server的地址信息,若是是Eureka Server集羣,多個節點使用逗號','分割。
eureka.client.serviceUrl.defaultZone=http://server1:8080/eureka/,http://server2:8080/eureka/

2)啓動類配置:

@EnableEurekaClient
@SpringBootApplication
public class UserServiceApplication {

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

8、CAP定理

CAP原則又稱CAP定理,指的是在一個分佈式系統中,Consistency(數據一致性)、 Availability(服務可用性)、Partition tolerance(分區容錯性),三者不可兼得。

性質 描述
數據一致性
(Consistency)
從客戶端角度來講,客戶端請求分佈式集羣中的任何節點獲取到的數據都是最新的數據;
從服務端角度來講,服務端每次執行更新數據操做後都須要同步到集羣中的其餘節點。
服務可用性
(Availability)
即服務一直可用,每個客戶端請求在合理時間內都能獲得合理的服務端響應,而不會出現用戶操做失敗或者請求超時等用戶體驗很差的狀況。
分區容錯性
(Partition tolerance)
分佈式系統在網絡分區或者節點故障的狀況下,仍能正常向外提供一致性或者可用性服務,分佈式系統外觀看起來像是一個總體,集羣內部雖然有節點故障,可是系統仍能知足用戶使用需求,不會影響用戶體驗

因爲三者不可兼得,因此放棄任何一個都會帶來相應的影響:

分類 影響
CA
(放棄P)
若是放棄P(不容許分區),那麼數據能夠保證一致性和可用性,可是單節點服務不具有系統擴展性,違背了分佈式系統的設計初衷,因此分佈式系統不可避免地都會使用P原則。
CP
(放棄A)
若是放棄A(不保證服務可用性),每次當某臺服務器數據更新後都要向集羣中其餘節點同步數據,只有全部節點同步完數據後,纔會從新接受客戶端請求,這個過程可能要耗時很長,就會形成一段時間內服務不可用,用戶請求超時報錯等問題,犧牲用戶體驗
AP
(放棄C)
這裏所說的放棄一致性,並非徹底放棄數據一致性,而是放棄數據的強一致性,而保留數據的最終一致性。一旦網絡分區發生,各節點之間數據不能同步,爲了保證高可用,服務器只能使用本地的緩存數據,形成全局的數據不一致性。典型的例子就是搶購場景,用戶前幾秒在頁面看見還有貨(優先保證服務可用性),下單時會提示已售罄(此時須要保證數據一致性),犧牲少量用戶體驗,但不會形成嚴重的網絡阻塞

zookeeper 做爲經常使用的註冊中心,與 eureka 有很大的區別:

  • zookeeper 是 CP 型的,eureka 是 AP 型的,前者在註冊中心故障時更傾向於保證數據一致性,後者更傾向於保證服務可用性;
  • zookeeper 經過選舉算法產生一個 leader,由 leader 向外提供註冊發現服務,其餘的 slaver 則經過訂閱監聽同步 leader 的信息,當 leader 宕機時,zookeeper 會暫停向外提供服務,經過選舉算法從新選舉 leader 後再向外提供服務,選舉過程當中會進行 leader 和 slaver 數據的同步,保證了數據的一致性;eureka 當某個註冊中心宕機後,若是有新的服務要註冊到該註冊中心,會根據配置的 serviceUrl 屬性,註冊到下一個 eurekaServer 節點,保證了服務的可用性,各個 eurekaServer 節點之間的數據並不保證明時一致性,各節點之間經過網絡通訊完成數據同步保證數據的最終一致性;
  • 關於客戶端監聽服務端的變化,zookeeper 經過訂閱方式來實現,eureka 經過輪詢方式來實現;
  • zookeeper 除了能夠提供註冊中心服務外,還能夠提供存儲等其餘服務,eureka 則是一個單純的註冊中心。
相關文章
相關標籤/搜索