1. 程式人生 > >Spring Cloud第三篇 | 搭建高可用Eureka註冊中心

Spring Cloud第三篇 | 搭建高可用Eureka註冊中心

​本文是Spring Cloud專欄的第三篇文章,瞭解前兩篇文章內容有助於更好的理解後面文章:

  1. Spring Cloud第一篇 | Spring Cloud前言及其常用元件介紹概覽

  2. Spring Cloud第二篇 | 使用並認識Eureka註冊中心

一、Eureka註冊中心高可用叢集概述

1-1、傳統架構

    在微服務架構的這種分散式系統中,我們要充分考慮各個微服務元件的高可用性問題,不能有單點故障,由於註冊中心Eureka本身也是一個服務,如果它只有一個節點,那麼它有可能發生故障,這樣我們就不能註冊與查詢服務了,所以我們需要—個高可用的服務註冊中心,這就需要通過註冊中心叢集來解決。Eureka服務註冊中心它本身也是一個服務,它也可以看做是一個提供者,又可以看做是一個消費者,我們之前通過配置eureka.client.register-with-eureka= false讓註冊中心不註冊自己,但是我們可以向其他註冊中心註冊自己。

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

二、Eureka註冊中心高可用叢集搭建

    Eureka註冊中心高可用叢集就是各個註冊中心相互註冊

    1、我們複製Eureka服務端(springcloud-eureka-server)的application.yml為application-eureka8701.yml,application-eureka8702.yml,我們讓8701和8702的Eureka服務相互註冊。

修改application-eureka8701.yml相應的配置如下:

spring:
  application:
    name: springcloud-eureka-server
server:
  port: 8701
#設定該服務中心的hostname,指定ip,該例項名稱不能重複
eureka:
  instance:
    hostname: eureka8701
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://eureka8702:8702/eureka

    修改application-eureka8701.yml相應的配置如下

spring:
  application:
    name: springcloud-eureka-server
server:
  port: 8702
#設定該服務中心的hostname,指定ip,該例項名稱不能重複
eureka:
  instance:
    hostname: eureka8702
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://eureka8701:8701/eureka

    2、複製SpringcloudEurekaServerApplication啟動類命名為SpringcloudEureka8701ServerApplication,SpringcloudEureka8702ServerApplication,滑鼠放在啟動類上右鍵選擇如圖

    然在啟動類SpringcloudEureka8701ServerApplication新增-Dspring.profiles.active=eureka8701

同理8702啟動類操作也是一樣,此處省略。

    3、為了讓eureka8701和eureka8702能夠被正確相互訪問到,同步資料,如果不能相互訪問,Eureka服務中的資料不能同步共享,我們需要在C:\Windows\System32\drivers\etc目錄下的hosts檔案中新增兩行配置,如下:

127.0.0.1 eureka8701
127.0.0.1 eureka8702

    4、啟動兩個SpringcloudEureka8701ServerApplication,SpringcloudEureka8702ServerApplication服務我們可以看到註冊成功了。

Eureka8702也是如此,到此Eureka服務叢集搭建完畢

三、Eureka詳解

1、服務消費者模式

1-1、獲取服務

    消費者啟動的時候,使用服務別名,會發送一個rest請求到服務註冊中心獲取對應的服務資訊,然後會快取到本地jvm客戶端中,同時客戶端每隔30秒從伺服器上更新一次。

    可以通過eureka.client.registry-fetch-interval-seconds=30引數進行修改,該配置預設值為30, 單位為秒。

1-2、服務下線

    在系統執行過程中必然會面臨關閉或重啟服務的某個例項的情況,在服務關閉期間我們自然不希望客戶端會繼續呼叫關閉了的例項。所以在客戶端程式中,當服務例項正常的關閉操作時,它會觸發一個服務下線的REST請求給Eureka Server, 告訴服務中心:“我要下線了”。服務端在接收到請求之後,將該服務狀態置為下線(DOWN),並將該下線事件傳播出去。

2、服務註冊模式

2-1、失效剔除

    有些時候,我們的服務例項並不一定會正常下線,可能由於記憶體溢位、網路故障原因使得服務不能正常工作,而服務註冊中心並未收到“服務下線”的請求。為了從服務表中將這些無法提供服務的例項剔除,Eureka Server 在啟動的時候會建立一個定時任務預設每隔一段時間(預設為60秒eureka.server.eviction-interval-timer-in-ms=6000L)將當前清單中超時(預設為90秒eureka.instance.lease-expiration-duration-in-seconds= 90)沒有續約的服務踢除出去

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

    當我們在本地除錯基於Eureka的程式時,基本上都會碰到這樣一個問題, 在服務主中心的資訊面板中出現類似下面的紅色警告資訊,在開發測試時,需要頻繁地重啟微服務例項,但是我們很少會把eureka server一起重啟(因為在開發過程中不會修改eureka註冊中心),當一分鐘內收到的心跳數大量減少時,會觸發該保護機制。可以在eureka管理介面看到Renews threshold和Renews(last min),當後者(最後一分鐘收到的心跳數)小於前者(心跳閾值)的時候,觸發保護機制,會出現紅色的警告:

    實際上,該警告就是觸發了Eureka Server的自我保護機制,服務註冊到Eureka Server之後,會維護個心跳連線, 告訴Eureka Server自己還活著。Eureka Server在執行期間,會統計客戶端節點的心跳失敗的比例在15分鐘之內是否低於85%如果出現低於的情況,如果低於85%,那就觸發自我保護機制,單機除錯的時候很容易滿足,實際在生產環境上通常是由於網路不穩定導致),Eureka Server會將當前的例項註冊資訊保護起來,讓這些例項不會過期,儘可能保護這些註冊資訊。但是,在這段保護期間內例項若出現問題,那麼客戶端很容易拿到實際已經不存服務例項,會出現呼叫失敗的情況,所以客戶端必須要有容錯機制,比如可以使用請使用重試、斷路器等機制。

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

    Eureka通過“自我保護模式”來解決這個問題——當 Eureka Server節點在短時間內丟失過多客戶端時(可能發生了網路分割槽故障),那麼就會把這個微服務節點進行保護。一旦進入自我保護模式, Eureka server就會保護服務登錄檔中的資訊,不刪除服務登錄檔中的資料(也就是不會登出任何微服務)。當網路故障恢復後,該 Eureka Server節點會再自動退出自我保護模式。所以,自我保護模式是一種應對網路異常的安全保護措施,它的架構哲學是寧可同時保留所有微服務(健康的微服務和不健康的微服務都會保留),也不盲目登出任何健康的微服務,使用自我保護模式,可以讓Eureka叢集更加的健壯、穩定當然也可以使用配置項: eureka.server.enable-self-preservation=fase禁用自我保護模式。

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

    Eureka的自我保護模式是有意義的,該模式被啟用後,它不會從註冊列表中剔除因長時間沒收到心跳導致註冊過期的服務,而是等待修復,直到心跳恢復正常之後,它自動退出自我保護模式。這種模式旨在避免因網路分割槽故障導致服務不可用的問題。

    例如,兩個微服務客戶端例項A和B之間有呼叫的關係,A是消費者,B是提供者,但是由於網路故障,B未能及時向Eureka傳送心跳續約,這時候 Eureka不能簡單的將B從登錄檔中剔除,因為如果剔除了,A就無法從Eureka伺服器中獲取B註冊的服務,但是這時候B服務是可用的;所以, Eureka的自我保護模式最好還是開啟它。

2-3、關閉自我保護的相關配置如下

  • 服務端配置

eureka:
  server:
    enable-self-preservation: false
    #eureka server清理無效節點的時間間隔,預設60000毫秒,即60秒
    eviction-interval-timer-in-ms: 60000 # 單位毫秒
  • 客戶端配置

# 心跳檢測檢測與續約時間,測試時將值設定設定小些,保證服務關閉後註冊中心能及時踢出服務
eureka:
  instance:
    # 每間隔1s,向服務端傳送一次心跳,證明自己依然“存活”
    lease-renewal-interval-in-seconds: 1
    # 告訴服務端,如果我2s之內沒有給你發心跳,就代表我“死”了,請將我踢掉
    lease-expiration-duration-in-seconds: 2
  • 關閉自我保護模式Eureka服務端顯示如下:

 

案例原始碼地址:https://gitee.com/coding-farmer/spirngcloud-learn