SpringCloud (一) Eureka

西涼馬戳戳發表於2021-12-22

Eureka

  1. Eureka 是一個服務治理元件,它主要包括服務註冊和服務發現,主要用來搭建服務註冊中心。
  2. Eureka 是一個基於 REST 的服務,用來定位服務,進行中間層伺服器的負載均衡和故障轉移。
  3. Eureka Server 作為服務註冊的服務端,它是服務註冊中心,而系統中的其他微服務,使用 Eureka 的客戶端連線到 Eureka
  4. Server 服務端,並維持心跳連線,Eureka 客戶端是一個 Java 客戶端,用來簡化與伺服器的互動、負載均衡,服務的故障切換等

Eureka 與 Zookeeper 的比較

  • Zookeeper 保證 CP(保證強一致性)
    在 ZooKeeper 中,當 master 節點因為網路故障與其他節點失去聯絡時,剩餘節點會重新進行 leader 選舉,但是問題在於,選舉 leader 需要一定時間, 且選舉期間整個 ZooKeeper 叢集都是不可用的,這就導致在選舉期間註冊服務癱瘓。
    在雲部署的環境下,因網路問題使得 ZooKeeper 叢集失去 master 節點是大概率事件,雖然服務最終能夠恢復,但是在選舉時間內導致服務註冊長期不可用是難以容忍的。
  • Eureka 保證 AP
    Eureka 優先保證可用性,Eureka 各個節點是平等的,某幾個節點掛掉不會影響正常節點的工作,剩餘的節點依然可以提供註冊和查詢服務。而 Eureka 的客戶端在向某個 Eureka 註冊或時如果發現連線失敗,則會自動切換至其它節點,只要有一臺 Eureka 還在,就能保證註冊服務可用(保證可用性),只不過查到的資訊可能不是最新的(不保證強一致性)。

配置 Eureka 服務註冊中心

  1. 建立一個 SpringBoot 專案,並且新增 SpringBoot 的相關依賴;springcloud-eureka-server

  2. 新增 eureka 的依賴

    <dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
    </dependency>
    
  3. 在 Spring Boot 的入口類上新增一個@EnableEurekaServer 註解,用於開啟 Eureka 註冊中心服務端

  4. 在 application.yml檔案中配置 Eureka 服務註冊中心資訊:

    # 應用名稱
    spring:
      application:
        name: EurekaServer
    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
    
  5. 啟動main,訪問 http://localhost:8761/

Eureka 服務註冊中心註冊服務

  1. 新建spring boot專案並匯入eureka 客戶端依賴:

    <dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    
  2. 在main上新增@EnableEurekaClient 註解

  3. 配置服務名稱和註冊中心地址

    spring:
      application:
        name: EurekaClient
    server:
      port: 8762
    eureka:
      client:
        register-with-eureka: true
        fetch-registry: true
        service-url:
          defaultZone: http://localhost:8761/eureka
      instance:
        prefer-ip-address: true
    
  4. 啟動執行之後,通過在瀏覽器位址列訪問我們之前搭建好的 eureka 註冊

Eureka 註冊中心高可用叢集

由於註冊中心 eureka 本身也是一個服務,如果它只有一個節點,那麼它有可能發生故障,這樣我們就不能註冊與查詢服務了,所以我們需要一個高可用的服務註冊中心,這就需要通過註冊中心叢集來解決。

Eureka Server 的高可用實際上就是將自己作為服務向其他服務註冊中心註冊自己,這樣就會形成一組互相註冊的服務註冊中心,進而實現服務清單的互相同步,往註冊中心 A 上註冊的服務,可以被複制同步到註冊中心 B 上,所以從任何一臺註冊中心上都能查詢到已經註冊的服務,從而達到高可用的效果。

  1. 在 8761 的配置檔案中,讓它的 service-url 指向 8763,在 8763 的配置檔案中讓它的 service-url 指向 8761

    server:
      port: 8761
    eureka:
      instance:
        hostname: localhost
      client:
        register-with-eureka: false
        fetch-registry: false
        service-url:
          defaultZone: http://${eureka.instance.hostname}:8763/eureka
    
    server:
      port: 8763
    eureka:
      instance:
        hostname: localhost
      client:
        register-with-eureka: false
        fetch-registry: false
        service-url:
          defaultZone: http://${eureka.instance.hostname}:8761/eureka
    
  2. 然後在本地 hosts 檔案配置:C:\Windows\System32\drivers\etc\hosts

    127.0.0.1 eureka8761

    127.0.0.1 eureka8763

  3. 分別啟動兩個註冊中心,訪問兩個註冊中心頁面,觀察註冊中心頁面是否正常

  4. 在eureka-client服務中配置:

    eureka:
      client:
        register-with-eureka: true
        fetch-registry: true
        service-url:
          defaultZone: http://localhost:8761/eureka, http://localhost:8763/eureka
    
  5. 啟動服務提供者服務,然後觀察註冊中心頁面,可以看到服務會在兩個註冊中心上都註冊成功

Eureka 服務註冊中心自我保護機制

當 Eureka 註冊中心進入自我保護模式時,在 Eureka Server 首頁會輸出如下警告資訊:

EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY'RE NOT. RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPIRED JUST TO BE SAFE.

在沒有 Eureka 自我保護的情況下,如果 Eureka Server 在一定時間內沒有接收到某個微服務例項的心跳,Eureka Server 將會登出該例項,但是當發生網路分割槽故障時,那麼微服務與 Eureka Server 之間將無法正常通訊,以上行為可能變得非常危險了——因為微服務本身其實是正常的,此時不應該登出這個微服務,如果沒有自我保護機制,那麼 Eureka Server 就會將此服務登出掉。

Eureka 通過“自我保護模式”來解決這個問題——當 Eureka Server 節點在短時間內丟失過多客戶端時(可能發生了網路分割槽故障),那麼就會把這個微服務節點進行保護。一旦進入自我保護模式,Eureka Server 就會保護服務登錄檔中的資訊,不刪除服務登錄檔中的資料(也就是不會登出任何微服務)。當網路故障恢復後,該 Eureka Server 節點會再自動退出自我保護模式。

但是 Eureka Server 自我保護模式也會給我們帶來一些困擾,如果在保護期內某個服務提供者剛好非正常下線了,此時服務消費者就會拿到一個無效的服務例項,此時會呼叫失敗,對於這個問題需要服務消費者端具有一些容錯機制,如重試,斷路器等。

自我保護常用幾個配置:

  1. 伺服器端

    #測試時關閉自我保護機制,保證不可用服務及時踢出

    eureka.server.enable-self-preservation=false
    
  2. 客戶端

    #每間隔 2s,向服務端傳送一次心跳,證明自己依然"存活"

    eureka.instance.lease-renewal-interval-in-seconds=2 
    

    #告訴服務端,如果我 10s 之內沒有給你發心跳,就代表我故障了,將我踢出掉

    eureka.instance.lease-expiration-duration-in-seconds=10
    

相關文章