1. 程式人生 > 實用技巧 >SpringCloud學習筆記【四】:Eureka的自我保護機制

SpringCloud學習筆記【四】:Eureka的自我保護機制

目錄

Eureka的自我保護機制

本篇要點

  • 介紹Eureka的自我保護機制。
  • 介紹CAP原則。
  • 介紹為什麼需要自我保護。
  • 介紹如何禁止自我保護機制

Eureka的自我保護

保護模式主要用於一組客戶端和Eureka Server之間存在網路分割槽場景下的保護。一旦進入保護模式,Eureka Server將會嘗試保護其服務登錄檔中的資訊,不再刪除服務登錄檔中的資料,也就是不會登出任何微服務

我們之前在註冊之後,強項停止某個微服務,就會出現下面這段紅字,此時就代表Eureka已經進入保護模式。

簡單來說:如果某個時刻某個微服務不可用了,Eureka不會立即對其進行清理,反而會依舊對該微服務資訊進行儲存。屬於分散式CAP原則的AP分支【可用性和分割槽容忍性】。

CAP是啥?

直接看看百度百科給出的解釋吧:

CAP原則又稱CAP定理,指的是在一個分散式系統中,一致性(Consistency)、可用性(Availability)、分割槽容錯性(Partition tolerance)。CAP 原則指的是,這三個要素最多隻能同時實現兩點,不可能三者兼顧。

  • 一致性(C):在分散式系統中的所有資料備份,在同一時刻是否同樣的值。(等同於所有節點訪問同一份最新的資料副本)

  • 可用性(A):在叢集中一部分節點故障

    後,叢集整體是否還能響應客戶端的讀寫請求。(對資料更新具備高可用性)

  • 分割槽容忍性(P):以實際效果而言,分割槽相當於對通訊的時限要求。系統如果不能在時限內達成資料一致性,就意味著發生了分割槽的情況,必須就當前操作在C和A之間做出選擇。

CAP原則的精髓就是要麼AP,要麼CP,要麼AC,但是不存在CAP。如果在某個分散式系統中資料無副本, 那麼系統必然滿足強一致性條件, 因為只有獨一資料,不會出現資料不一致的情況,此時C和P兩要素具備,但是如果系統發生了網路分割槽狀況或者宕機,必然導致某些資料不可以訪問,此時可用性條件就不能被滿足,即在此情況下獲得了CP系統,但是CAP不可同時滿足。

為什麼會產生Eureka的自我保護機制

預設情況下,如果EurekaServer在一定時間內沒有收到某個微服務例項的心跳,EurekaServer將會登出該例項【預設90s】。但是當網路分割槽故障發生【延時、卡頓、擁擠】時候,微服務與EurekaServer之間無法正常通訊,以上行為可能變得非常危險了。

此時微服務本身其實是健康的,本不應該登出這個微服務,Eureka通過自我保護模式來解決這個問題:當EurekaServer節點在短時間內丟失過多客戶端時候(可能發生了網路分割槽故障),那麼這個節點就會進入自我保護模式了。

綜上:自我保護模式是一種應對網路異常的安全保護措施,它的涉及哲學就是寧可同時保留錯誤的服務註冊資訊,也不盲目登出任何可能健康的服務例項。老話反說就是:寧可放過三千,也不錯殺一個。自我保護模式讓Eureka叢集更加健壯穩定。

如何禁止自我保護

自我保護是可配置的,預設是開啟的,我們也可以通過配置禁止它,這裡演示一下如何禁止。

這一項配置由eureka.client.enable-self-preservation決定,我們讓它變為false即可。

eureka.client.server.enable-self-preservation=false # 預設是true的

關閉之後,我們再次啟動server7001,訪問localhost:7001,出現以下警示:

表明註冊中心的自我保護模式已經成功關閉。

為了進行測試,我們使用單機版的Eureka環境,將cloud-eureka-server7001的配置改為如下:

eureka:
  instance:
    hostname: eureka7001.com #eureka服務端的例項名稱
  client:
    register-with-eureka: false     #false表示不向註冊中心註冊自己。
    fetch-registry: false     #false表示自己端就是註冊中心,我的職責就是維護服務例項,並不需要去檢索服務
    service-url:
      # 設定與Eureka Server互動的地址查詢服務和註冊服務都需要依賴這個地址
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
  server:
    #關閉自我保護機制,保證不可用服務被及時踢除
    enable-self-preservation: false
    # 清理增量佇列中過期的頻率
    eviction-interval-timer-in-ms: 2000
  • 關閉自我保護機制enable-self-preservation
  • 每2秒清理一次失效的服務:eviction-interval-timer-in-ms

為了能更快地看到效果,將cloud-provider-payment8001 的配置也進行修改:

eureka:
  client:
    #表示是否將自己註冊進EurekaServer預設為true。
    register-with-eureka: true
    #是否從EurekaServer抓取已有的註冊資訊,預設為true。單節點無所謂,叢集必須設定為true才能配合ribbon使用負載均衡
    fetchRegistry: true
    service-url:
      #單機版
      defaultZone: http://localhost:7001/eureka
  instance:
    instance-id: payment8001
    #訪問路徑可以顯示IP地址
    prefer-ip-address: true
    #Eureka客戶端向服務端傳送心跳的時間間隔,單位為秒(預設是30秒)
    lease-renewal-interval-in-seconds: 1
    #Eureka服務端在收到最後一次心跳後等待時間上限,單位為秒(預設是90秒),超時將剔除服務
    lease-expiration-duration-in-seconds: 2
  • 設定Eureka客戶端向服務端傳送心跳的時間間隔為1s。
  • Eureka服務端在收到最後一次心跳後等待時間上限為2s。

接著我們先啟動7001,才啟動8001:

關閉8001:

此時,測試成功,一旦關閉自我保護模式,只要服務因為各種原因出現通訊異常,服務端不會再儲存他們的資訊,而是選擇剔除 。

原始碼下載

本系列文章為《尚矽谷SpringCloud教程》的學習筆記【版本稍微有些不同,後續遇到bug再做相關說明】,主要做一個長期的記錄,為以後學習的同學提供示例,程式碼同步更新到Gitee:https://gitee.com/tqbx/spring-cloud-learning,並且以標籤的形式詳細區分每個步驟,這個系列文章也會同步更新。