1. 程式人生 > 其它 >Sentinel:Spring Cloud Alibaba高可用流量控制組件

Sentinel:Spring Cloud Alibaba高可用流量控制組件

Sentinel 是由阿里巴巴中介軟體團隊開發的開源專案,是一種面向分散式微服務架構的輕量級高可用流量控制組件。

Sentinel 主要以流量為切入點,從流量控制、熔斷降級、系統負載保護等多個維度幫助使用者保護服務的穩定性。

Sentinel 具有以下優勢:

    • 豐富的應用場景:Sentinel 承接了阿里巴巴近 10 年的“雙十一”大促流量的核心場景,例如秒殺(將突發流量控制在系統可以承受的範圍)、訊息削峰填谷、叢集流量控制、實時熔斷下游不可用服務等。
    • 完備的實時監控:Sentinel 提供了實時監控功能。使用者可以在控制檯中看到接入應用的單臺機器的秒級資料,甚至是 500 臺以下規模叢集的彙總執行情況。
    • 廣泛的開源生態:Sentinel 提供了開箱即用的與其它開源框架或庫(例如 Spring Cloud、Apache Dubbo、gRPC、Quarkus)的整合模組。我們只要在專案中引入相應的依賴並進行簡單的配置即可快速地接入 Sentinel。此外,Sentinel 還提供 Java、Go 以及 C++ 等多語言的原生實現。
    • 完善的 SPI 擴充套件機制:Sentinel 提供簡單易、完善的 SPI 擴充套件介面,我們可以通過實現這些擴充套件介面快速地定製邏輯,例如定製規則管理、適配動態資料來源等。

SPI ,全稱為 Service Provider Interface,是一種服務發現機制。它可以在 ClassPath 路徑下的 META-INF/services 資料夾查詢檔案,並自動載入檔案中定義的類。

從功能上來說,Sentinel 與 Spring Cloud Netfilx Hystrix 類似,但 Sentinel 要比 Hystrix 更加強大,例如 Sentinel 提供了流量控制功能、比 Hystrix 更加完善的實時監控功能等等。

Sentinel 的組成

Sentinel 主要由以下兩個部分組成:

  • Sentinel 核心庫:Sentinel 的核心庫不依賴任何框架或庫,能夠運行於 Java 8 及以上的版本的執行時環境中,同時對 Spring Cloud、Dubbo 等微服務框架提供了很好的支援。
  • Sentinel 控制檯(Dashboard):Sentinel 提供的一個輕量級的開源控制檯
    ,它為使用者提供了機器自發現、簇點鏈路自發現、監控、規則配置等功能。

Sentinel 核心庫不依賴 Sentinel Dashboard,但兩者結合使用可以有效的提高效率,讓 Sentinel 發揮它最大的作用。

Sentinel 的基本概念

Sentinel 的基本概念有兩個,它們分別是:資源和規則。

基本概念 描述
資源 資源是 Sentinel 的關鍵概念。它可以是 Java 應用程式中的任何內容,例如由應用程式提供的服務或者是服務裡的方法,甚至可以是一段程式碼。

我們可以通過 Sentinel 提供的 API 來定義一個資源,使其能夠被 Sentinel 保護起來。通常情況下,我們可以使用方法名、URL 甚至是服務名來作為資源名來描述某個資源。
規則 圍繞資源而設定的規則。Sentinel 支援流量控制、熔斷降級、系統保護、來源訪問控制和熱點引數等多種規則,所有這些規則都可以動態實時調整

 

@SentinelResource 註解

@SentinelResource 註解是 Sentinel 提供的最重要的註解之一,它還包含了多個屬性,如下表。

屬性 說明 必填與否 使用要求
value 用於指定資源的名稱 必填 -
entryType entry 型別 可選項(預設為 EntryType.OUT) -
blockHandler 服務限流後會丟擲 BlockException 異常,而 blockHandler 則是用來指定一個函式來處理 BlockException  異常的。

簡單點說,該屬性用於指定服務限流後的後續處理邏輯
可選項
  • blockHandler 函式訪問範圍需要是 public;
  • 返回型別需要與原方法相匹配;
  • 引數型別需要和原方法相匹配並且最後加一個額外的引數,型別為 BlockException;
  • blockHandler 函式預設需要和原方法在同一個類中,若希望使用其他類的函式,則可以指定 blockHandler 為對應的類的 Class 物件,注意對應的函式必需為 static 函式,否則無法解析。
blockHandlerClass 若 blockHandler 函式與原方法不在同一個類中,則需要使用該屬性指定 blockHandler 函式所在的類。 可選項
  • 不能單獨使用,必須與 blockHandler 屬性配合使用;
  • 該屬性指定的類中的 blockHandler 函式必須為 static 函式,否則無法解析。
fallback 用於在丟擲異常(包括 BlockException)時,提供 fallback 處理邏輯。

fallback 函式可以針對所有型別的異常(除了 exceptionsToIgnore 裡面排除掉的異常型別)進行處理。
可選項
  • 返回值型別必須與原函式返回值型別一致;
  • 方法引數列表需要和原函式一致,或者可以額外多一個 Throwable 型別的引數用於接收對應的異常;
  • fallback 函式預設需要和原方法在同一個類中,若希望使用其他類的函式,則可以指定 fallbackClass 為對應的類的 Class 物件,注意對應的函式必需為 static 函式,否則無法解析。
fallbackClass  若 fallback 函式與原方法不在同一個類中,則需要使用該屬性指定 blockHandler 函式所在的類。 可選項
  • 不能單獨使用,必須與 fallback 或 defaultFallback  屬性配合使用;
  • 該屬性指定的類中的 fallback 函式必須為 static 函式,否則無法解析。
defaultFallback 預設的 fallback 函式名稱,通常用於通用的 fallback 邏輯(即可以用於很多服務或方法)。

預設 fallback 函式可以針對所以型別的異常(除了 exceptionsToIgnore 裡面排除掉的異常型別)進行處理。
可選項
  • 返回值型別必須與原函式返回值型別一致;
  • 方法引數列表需要為空,或者可以額外多一個 Throwable 型別的引數用於接收對應的異常;
  • defaultFallback 函式預設需要和原方法在同一個類中。若希望使用其他類的函式,則可以指定 fallbackClass 為對應的類的 Class 物件,注意對應的函式必需為 static 函式,否則無法解析。
exceptionsToIgnore 用於指定哪些異常被排除掉,不會計入異常統計中,也不會進入 fallback 邏輯中,而是會原樣丟擲。 可選項 -

 注:在 Sentinel 1.6.0 之前,fallback 函式只針對降級異常(DegradeException)進行處理,不能處理業務異常。 

Sentinel 控制檯

Sentinel 提供了一個輕量級的開源控制檯 Sentinel Dashboard,它提供了機器發現與健康情況管理、監控(單機和叢集)、規則管理與推送等多種功能。

Sentinel 控制檯提供的功能如下:

  • 檢視機器列表以及健康情況:Sentinel 控制檯能夠收集 Sentinel 客戶端傳送的心跳包,判斷機器是否線上。
  • 監控(單機和叢集聚合):Sentinel 控制檯通過 Sentinel 客戶端暴露的監控 API,可以實現秒級的實時監控。
  • 規則管理和推送:通過 Sentinel 控制檯,我們還能夠針對資源定義和推送規則。
  • 鑑權:從 Sentinel 1.6.0 起,Sentinel 控制檯引入基本的登入功能,預設使用者名稱和密碼都是 sentinel。

Sentinel Dashboard 是我們配置和管理規則(例如流控規則、熔斷降級規則等)的重要入口之一。通過它,我們不僅可以對規則進行配置和管理,還能實時檢視規則的效果。

安裝 Sentinel 控制檯

下面我們就來演示下,如何下載和安裝 Sentinel 控制檯,具體步驟如下。

例項:Sentinel:Spring Cloud Alibaba高可用流量控制組件

Sentinel 的開發流程

Sentinel 的開發流程如下:

  1. 引入 Sentinel 依賴:在專案中引入 Sentinel 的依賴,將 Sentinel 整合到專案中;
  2. 定義資源:通過對主流框架提供適配或 Sentinel 提供的顯式 API 和註解,可以定義需要保護的資源,此外 Sentinel 還提供了資源的實時統計和呼叫鏈路分析;
  3. 定義規則:根據實時統計資訊,對資源定義規則,例如流控規則、熔斷規則、熱點規則、系統規則以及授權規則等。
  4. 檢驗規則是否在生效:執行程式,檢驗規則是否生效,檢視效果。

引入 Sentinel 依賴

為了減少開發的複雜程度,Sentinel 對大部分的主流框架都進行了適配,例如 Web Servlet、Dubbo、Spring Cloud、gRPC、Spring WebFlux 和 Reactor 等。以 Spring Cloud 為例,我們只需要引入 spring-cloud-starter-alibaba-sentinel 的依賴,就可以方便地將 Sentinel 整合到專案中。

下面我們就通過一個簡單的例項,演示如何將 Sentinel 整合到 Spring Cloud 專案中,步驟如下。

例項:Sentinel:Spring Cloud Alibaba高可用流量控制組件

定義資源

資源是 Sentinel 中的核心概念之一。在專案開發時,我們只需要考慮這個服務、方法或程式碼是否需要保護,如果需要保護,就可以將它定義為一個資源。

Sentinel 為我們提供了多種定義資源的方式:

  • 適配主流框架自動定義資源
  • 通過 SphU 手動定義資源
  • 通過 SphO 手動定義資源
  • 註解方式定義資源

適配主流框架自動定義資源

Sentinel 對大部分的主流框架都進行了適配,我們只要引入相關的適配模組(例如 spring-cloud-starter-alibaba-sentinel),Snetinel 就會自動將專案中的服務(包括呼叫端和服務端)定義為資源,資源名就是服務的請求路徑。此時,我們只要再定義一些規則,這些資源就可以享受到 Sentinel 的保護。

 

 

 

 

通過 SphU 手動定義資源

Sentinel 提供了一個名為 SphU 的類,它包含的 try-catch 風格的 API ,可以幫助我們手動定義資源。

下面我們就通過一個例項,來演示下如何通過 SphU 定義資源。

例項:Sentinel:Spring Cloud Alibaba高可用流量控制組件

 

 

 

通過 SphO 手動定義資源

Sentinel 還提供了一個名為 SphO 的類,它包含了 if-else 風格的 API,能幫助我們手動定義資源。通過這種方式定義的資源,發生了限流之後會返回 false,此時我們可以根據返回值,進行限流之後的邏輯處理。

下面我們就通過一個例項,來演示下如何通過 SphO 定義資源。

例項:Sentinel:Spring Cloud Alibaba高可用流量控制組件

 

 

註解方式定義資源(推薦)

除了以上兩種方式外,我們還可以通過 Sentinel 提供的 @SentinelResource 註解定義資源。

下面我們就通過一個例項,來演示下如何通過 @SentinelResource 註解定義資源。

例項:Sentinel:Spring Cloud Alibaba高可用流量控制組件

 

 

Sentinel 流量控制

任何系統處理請求的能力都是有限的,但任意時間內到達系統的請求量往往是隨機且不可控的,如果在某一個瞬時時刻請求量急劇增,那麼系統就很有可能被瞬時的流量高峰沖垮。為了避免此類情況發生,我們都需要根據系統的處理能力對請求流量進行控制,這就是我們常說的“流量控制”,簡稱“流控”

Sentinel 作為一種輕量級高可用流量控制組件,流量控制是它最主要的工作之一。

我們可以針對資源定義流控規則,Sentinel 會根據這些規則對流量相關的各項指標進行監控。當這些指標當達到或超過流控規則規定的閾值時,Sentinel 會對請求的流量進行限制(即“限流”),以避免系統被瞬時的流量高峰沖垮,保障系統的高可用性。

一條流量規則主要由下表中的屬性組成,我們可以通過組合這些屬性來實現不同的限流效果。

屬性 說明 預設值
資源名 流控規則的作用物件。 -
閾值 流控的閾值。 -
閾值型別 流控閾值的型別,包括 QPS 或併發執行緒數。 QPS
針對來源 流控針對的呼叫來源。 default,表示不區分呼叫來源
流控模式 呼叫關係限流策略,包括直接、鏈路和關聯。 直接
流控效果 流控效果(直接拒絕、Warm Up、勻速排隊),不支援按呼叫關係限流。 直接拒絕

注:QPS 表示併發請求數,換句話說就是,每秒鐘最多通過的請求數。

同一個資源可以建立多條流控規則,Sentinel 會遍歷這些規則,直到有規則觸發限流或者所有規則遍歷完畢為止。

Sentinel 觸發限流時,資源會丟擲 BlockException 異常,此時我們可以捕捉 BlockException 來自定義被限流之後的處理邏輯。

注意:這裡我們主要講解 Sentinel 流控規則的定義與使用,至於詳細的流控規則配置,請參考 Sentinel 官方流控文件

通過 Sentinel 控制檯定義流控規則

我們可以通過 Sentinel 控制檯,直接對資源定義流控規則,操作步驟如下。

例項:Sentinel:Spring Cloud Alibaba高可用流量控制組件

使用 @SentinelResource 註解的 blockHandler 屬性時,需要注意以下事項:

  • blockHandler 函式訪問範圍需要是 public;
  • 返回型別需要與原方法相匹配;
  • 引數型別需要和原方法相匹配並且最後加一個額外的引數,型別為 BlockException;
  • blockHandler 函式預設需要和原方法在同一個類中,若希望使用其他類的函式,則可以指定 blockHandler 為對應的類的 Class 物件,注意對應的函式必需為 static 函式,否則無法解析。
  • 請務必新增 blockHandler 屬性來指定自定義的限流處理方法,若不指定,則會跳轉到錯誤頁(使用者體驗不好)。

通過程式碼定義流控規則

FlowRule 可以通過以下屬性定義流控規則,如下表。

屬性 說明 預設值
resource 資源名,即流控規則的作用物件 -
count 限流的閾值。 -
grade 流控閾值的型別,包括 QPS 或併發執行緒數 QPS
limitApp 流控針對的呼叫來源 default,表示不區分呼叫來源
strategy 呼叫關係限流策略,包括直接、鏈路和關聯 直接
controlBehavior 流控效果(直接拒絕、Warm Up、勻速排隊),不支援按呼叫關係限流 直接拒絕

下面我們就通過一個簡單的例項,來演示下如何通過程式碼定義流控規則,步驟如下。

例項:Sentinel:Spring Cloud Alibaba高可用流量控制組件

熔斷降級規則

除了流量控制以外,對呼叫鏈路中不穩定資源的熔斷降級,也是保障服務高可用的重要措施之一。

在分散式微服務架構中,一個系統往往由多個服務組成,不同服務之間相互呼叫,組成複雜的呼叫鏈路。如果鏈路上的某一個服務出現故障,那麼故障就會沿著呼叫鏈路在系統中蔓延,最終導致整個系統癱瘓。Sentinel 提供了熔斷降級機制就可以解決這個問題。

Sentinel 的熔斷降級機制會在呼叫鏈路中某個資源出現不穩定狀態時(例如呼叫超時或異常比例升高),暫時切斷對這個資源的呼叫,以避免區域性不穩定因素導致整個系統的雪崩。

熔斷降級作為服務保護自身的手段,通常在客戶端(呼叫端)進行配置,資源被熔斷降級最直接的表現就是丟擲 DegradeException 異常。

Sentinel 熔斷策略

Sentinel 提供了 3 種熔斷策略,如下表所示。

熔斷策略 說明
慢呼叫比例
(SLOW_REQUEST_RATIO)
選擇以慢呼叫比例作為閾值,需要設定允許的慢呼叫 RT(即最大響應時間),若請求的響應時間大於該值則統計為慢呼叫。

當單位統計時長(statIntervalMs)內請求數目大於設定的最小請求數目,且慢呼叫的比例大於閾值,則接下來的熔斷時長內請求會自動被熔斷。

經過熔斷時長後熔斷器會進入探測恢復狀態(HALF-OPEN 狀態),若接下來的一個請求響應時間小於設定的慢呼叫 RT 則結束熔斷,若大於設定的慢呼叫 RT 則再次被熔斷。
異常比例 (ERROR_RATIO) 當單位統計時長(statIntervalMs)內請求數目大於設定的最小請求數目且異常的比例大於閾值,則在接下來的熔斷時長內請求會自動被熔斷。

經過熔斷時長後熔斷器會進入探測恢復狀態(HALF-OPEN 狀態),若接下來的一個請求成功完成(沒有錯誤)則結束熔斷,否則會再次被熔斷。異常比率的閾值範圍是 [0.0, 1.0],代表 0% - 100%
異常數 (ERROR_COUNT) 單位統計時長內的異常數目超過閾值之後會自動進行熔斷。

經過熔斷時長後熔斷器會進入探測恢復狀態(HALF-OPEN 狀態),若接下來的一個請求成功完成(沒有錯誤)則結束熔斷,否則會再次被熔斷。

 注意:Sentinel 1.8.0 版本對熔斷降級特性進行了全新的改進升級,以上熔斷策略針對的是 Sentinel 1.8.0 及以上版本。

Sentinel 熔斷狀態

Sentinel 熔斷降級中共涉及 3 種狀態,熔斷狀態的之間的轉換過程如下圖。

 

 Sentinel 熔斷降級中共涉及 3 種狀態,如下表。

 

狀態 說明 觸發條件
熔斷關閉狀態
(CLOSED)
處於關閉狀態時,請求可以正常呼叫資源。 滿足以下任意條件,Sentinel 熔斷器進入熔斷關閉狀態:
  • 全部請求訪問成功。
  • 單位統計時長(statIntervalMs)內請求數目小於設定的最小請求數目。
  • 未達到熔斷標準,例如服務超時比例、異常數、異常比例未達到閾值。
  • 處於探測恢復狀態時,下一個請求訪問成功。
熔斷開啟狀態
(OPEN)
處於熔斷開啟狀態時,熔斷器會一定的時間(規定的熔斷時長)內,暫時切斷所有請求對該資源的呼叫,並呼叫相應的降級邏輯使請求快速失敗避免系統崩潰。 滿足以下任意條件,Sentinel 熔斷器進入熔斷開啟狀態:
  • 單位統計時長內請求數目大於設定的最小請求數目,且已達到熔斷標準,例如請求超時比例、異常數、異常比例達到閾值。
  • 處於探測恢復狀態時,下一個請求訪問失敗。
探測恢復狀態
(HALF-OPEN)
處於探測恢復狀態時,Sentinel 熔斷器會允許一個請求呼叫資源。則若接下來的一個請求成功完成(沒有錯誤)則結束熔斷,熔斷器進入熔斷關閉(CLOSED)狀態;否則會再次被熔斷,熔斷器進入熔斷開啟(OPEN)狀態。 在熔斷開啟一段時間(降級視窗時間或熔斷時長,單位為 s)後,Sentinel 熔斷器自動會進入探測恢復狀態。

Sentinel 熔斷規則屬性

Sentinel 熔斷降級規則包含多個重要屬性,如下表所示。

屬性 說明 預設值 使用範圍
資源名 規則的作用物件。 - 所有熔斷策略
熔斷策略 Sentinel 支援3 中熔斷策略:慢呼叫比例、異常比例、異常數策略。 慢呼叫比例 所有熔斷策略
最大 RT 請求的最大相應時間,請求的響應時間大於該值則統計為慢呼叫。 - 慢呼叫比例
熔斷時長 熔斷開啟狀態持續的時間,超過該時間熔斷器會切換為探測恢復狀態(HALF-OPEN),單位為 s。 - 所有熔斷策略
最小請求數 熔斷觸發的最小請求數,請求數小於該值時即使異常比率超出閾值也不會熔斷(1.7.0 引入)。 5 所有熔斷策略
統計時長 熔斷觸發需要統計的時長(單位為 ms),如 60*1000 代表分鐘級(1.8.0 引入)。 1000 ms 所有熔斷策略
比例閾值 分為慢呼叫比例閾值和異常比例閾值,即慢呼叫或異常呼叫佔所有請求的百分比,取值範圍 [0.0,1.0]。 - 慢呼叫比例 、異常比例
異常數 請求或呼叫發生的異常的數量。 - 異常數

 

Sentinel 實現熔斷降級過程

Sentinel 實現熔斷降級的步驟如下:

  1. 在專案中,使用 @SentinelResource 註解的 fallback 屬性可以為資源指定熔斷降級邏輯(方法)。
  2. 通過 Sentinel 控制檯或程式碼定義熔斷規則,包括熔斷策略、最小請求數、閾值、熔斷時長以及統計時長等。
  3. 若單位統計時長(statIntervalMs)內,請求數目大於設定的最小請求數目且達到熔斷標準(例如請求超時比例、異常數、異常比例達到閾值),Sentinel 熔斷器進入熔斷開啟狀態(OPEN)。
  4. 處於熔斷開啟狀態時, @SentinelResource 註解的 fallback 屬性指定的降級邏輯會臨時充當主業務邏輯,而原來的主邏輯則暫時不可用。當有請求訪問該資源時,會直接呼叫降級邏輯使請求快速失敗,而不會呼叫原來的主業務邏輯。
  5. 在經過一段時間(在熔斷規則中設定的熔斷時長)後,熔斷器會進入探測恢復狀態(HALF-OPEN),此時 Sentinel 會允許一個請求對原來的主業務邏輯進行呼叫,並監控其呼叫結果。
  6. 若請求呼叫成功,則熔斷器進入熔斷關閉狀態(CLOSED ),服務原來的主業務邏輯恢復,否則重新進入熔斷開啟狀態(OPEN)。

通過 Sentinel 控制檯定義熔斷降級規則

我們可以通過 Sentinel 控制檯直接對資源定義熔斷降級規則。

下面我們通過一個例項,來演示如何通過 Sentinel 控制檯,對資源定義降級規則。

例項:Sentinel:Spring Cloud Alibaba高可用流量控制組件

通過程式碼定義熔斷規則

 Sentinel 核心庫中提供了的一個名為 DegradeRuleManager 類,我們可以通過呼叫它的 loadRules() 方法來定義熔斷降級規則,該方法需要一個 DegradeRule 型別的 List 引數。

public static void loadRules(List<DegradeRule> rules) {
    try {
        currentProperty.updateValue(rules);
    } catch (Throwable var2) {
        RecordLog.error("[DegradeRuleManager] Unexpected error when loading degrade rules", var2);
    }
}

DegradeRule 類可以用來定義一條熔斷規則,它包含多個與熔斷規則相關的屬性,如下表。

屬性 說明 預設值
resource 資源名,即規則的作用物件  
grade 熔斷策略,支援慢呼叫比例/異常比例/異常數策略 慢呼叫比例
count 慢呼叫比例模式下為慢呼叫臨界 RT(超出該值計為慢呼叫);異常比例/異常數模式下為對應的閾值  
timeWindow 熔斷時長,單位為 s  
minRequestAmount 熔斷觸發的最小請求數,請求數小於該值時即使異常比率超出閾值也不會熔斷(1.7.0 引入) 5
statIntervalMs 統計時長(單位為 ms),如 60*1000 代表分鐘級(1.8.0 引入) 1000 ms
slowRatioThreshold 慢呼叫比例閾值,僅慢呼叫比例模式有效(1.8.0 引入)  

 下面我們就通過一個例項,演示下如何通過程式碼定義熔斷規則,步驟如下。

例項:Sentinel:Spring Cloud Alibaba高可用流量控制組件