1. 程式人生 > 程式設計 >SpringCloud-Alibaba-Sentinel服務降級,熱點限流,服務熔斷

SpringCloud-Alibaba-Sentinel服務降級,熱點限流,服務熔斷

前言:
除了流量控制以外,對呼叫鏈路中不穩定的資源進行熔斷降級也是保障高可用的重要措施之一。一個服務常常會呼叫別的模組,可能是另外的一個遠端服務、資料庫,或者第三方 API 等。例如,支付的時候,可能需要遠端呼叫銀聯提供的 API;查詢某個商品的價格,可能需要進行資料庫查詢。然而,這個被依賴服務的穩定性是不能保證的。如果依賴的服務出現了不穩定的情況,請求的響應時間變長,那麼呼叫服務的方法的響應時間也會變長,執行緒會產生堆積,最終可能耗盡業務自身的執行緒池,服務本身也變得不可用

在這裡插入圖片描述

熔斷策略
Sentinel 提供以下幾種熔斷策略:

慢呼叫比例 (SLOW_REQUEST_RATIO):選擇以慢呼叫比例作為閾值,需要設定允許的慢呼叫 RT(即最大的響應時間),請求的響應時間大於該值則統計為慢呼叫。當單位統計時長(statIntervalMs)內請求數目大於設定的最小請求數目,並且慢呼叫的比例大於閾值,則接下來的熔斷時長內請求會自動被熔斷。經過熔斷時長後熔斷器會進入探測恢復狀態(HALF-OPEN 狀態),若接下來的一個請求響應時間小於設定的慢呼叫 RT 則結束熔斷,若大於設定的慢呼叫 RT 則會再次被熔斷。

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

在這裡插入圖片描述

慢呼叫比例:
最大 RT:200意思是 在200毫秒處理完這個請求
比例閥值:1 意思是是 在200毫秒處理一個請求 你設定幾就就200毫秒處理幾個

熔斷時長:1意思是一秒內不可用
最小請求數:5 意思是 一秒5次請求

在這裡插入圖片描述
在這裡插入圖片描述

異常比例:
比例閥值:官網:(異常比率的閾值範圍是 [0.0,1.0],代表 0% - 100%)0.3意思錯誤的達到了百分之30的時候 觸發熔斷

熔斷時間:1的意思是一秒之間不可用
最小請求數:5一秒5個

在這裡插入圖片描述

異常數
異常數:3意思是超過3個異常,就是第4次進入熔斷服務降級,當第五次請求是對的就會恢復
熔斷時長:1秒

在這裡插入圖片描述

熱點引數限流
何為熱點?熱點即經常訪問的資料。很多時候我們希望統計某個熱點資料中訪問頻次最高的 Top K 資料,並對其訪問進行限制。比如:

商品 ID 為引數,統計一段時間內最常購買的商品 ID 並進行限制
使用者 ID 為引數,針對一段時間內頻繁訪問的使用者 ID 進行限制
熱點引數限流會統計傳入引數中的熱點引數,並根據配置的限流閾值與模式,對包含熱點引數的資源呼叫進行限流。熱點引數限流可以看做是一種特殊的流量控制,僅對包含熱點引數的資源呼叫生效。

在這裡插入圖片描述

示例:
這裡有兩個 引數一個是A 一個是B熱點限流是根據設定引數的下標設定的,下表是從0開始的,
@SentinelResource註解設定要限流的id, blockHandler設定返回可預知的響應體

 @GetMapping(value = "select/test")
 @SentinelResource(value = "test",blockHandler = "teat1")
 public String test(@RequestParam(value = "a",required = false) Integer a,@RequestParam(value = "b",required = false) Integer b){

 return "我是:Sentinel";

 }

設定的可預知的響應體這個的BlockException是必須的引數

 public String teat1(@RequestParam(value = "a",required = false)Integer b,BlockException e){

 return "沒錯我就是我了";

 }

配置
test是@SentinelResource(value = "test",blockHandler = "teat1")
引數索引:0就是0下標
單機閥值:1處理的個數
統計視窗時長 1是一秒處理完成

在這裡插入圖片描述

高階選項

在這裡插入圖片描述

引數型別:選擇引數的資料型別
引數值:1就引數如果等於1就限流
限流閥: 3就是3次

在這裡插入圖片描述

這些可以自己測試

在這裡插入圖片描述

服務熔斷

Sentinel 提供了 @SentinelResource 註解用於定義資源,並提供了 AspectJ 的擴充套件用於自動定義資源、處理 BlockException 等。

@SentinelResource 註解

@SentinelResource 用於定義資源,並提供可選的異常處理和 fallback 配置項。 @SentinelResource 註解包含以下屬性:

value:資源名稱,必需項(不能為空)
entryType:entry 型別,可選項(預設為 EntryType.OUT)
blockHandler / blockHandlerClass: blockHandler 對應處理 BlockException 的函式名稱,可選項。blockHandler 函式訪問範圍需要是 public,返回型別需要與原方法相匹配,引數型別需要和原方法相匹配並且最後加一個額外的引數,型別為 BlockException。blockHandler 函式預設需要和原方法在同一個類中。若希望使用其他類的函式,則可以指定 blockHandlerClass 為對應的類的 Class 物件,注意對應的函式必需為 static 函式,否則無法解析。
fallback / fallbackClass:fallback 函式名稱,可選項,用於在丟擲異常的時候提供 fallback 處理邏輯。fallback 函式可以針對所有型別的異常(除了 exceptionsToIgnore 裡面排除掉的異常型別)進行處理。fallback 函式簽名和位置要求:
返回值型別必須與原函式返回值型別一致;
方法引數列表需要和原函式一致,或者可以額外多一個 Throwable 型別的引數用於接收對應的異常。
fallback 函式預設需要和原方法在同一個類中。若希望使用其他類的函式,則可以指定 fallbackClass 為對應的類的 Class 物件,注意對應的函式必需為 static 函式,否則無法解析。
defaultFallback(since 1.6.0):預設的 fallback 函式名稱,可選項,通常用於通用的 fallback 邏輯(即可以用於很多服務或方法)。預設 fallback 函式可以針對所有型別的異常(除了 exceptionsToIgnore 裡面排除掉的異常型別)進行處理。若同時配置了 fallback 和 defaultFallback,則只有 fallback 會生效。defaultFallback 函式簽名要求:
返回值型別必須與原函式返回值型別一致;
方法引數列表需要為空,或者可以額外多一個 Throwable 型別的引數用於接收對應的異常。
defaultFallback 函式預設需要和原方法在同一個類中。若希望使用其他類的函式,則可以指定 fallbackClass 為對應的類的 Class 物件,注意對應的函式必需為 static 函式,否則無法解析。
exceptionsToIgnore(since 1.6.0):用於指定哪些異常被排除掉,不會計入異常統計中,也不會進入 fallback 邏輯中,而是會原樣丟擲。
1.8.0 版本開始,defaultFallback 支援在類級別進行配置。

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

特別地,若 blockHandler 和 fallback 都進行了配置,則被限流降級而丟擲 BlockException 時只會進入 blockHandler 處理邏輯。若未配置 blockHandler、fallback 和 defaultFallback,則被限流降級時會將 BlockException 直接丟擲(若方法本身未定義 throws BlockException 則會被 JVM 包裝一層 UndeclaredThrowableException)。

示例:

1,fallback處理java異常

@SentinelResource(value = "select",fallback = "ErrorFallback")

程式碼

 @GetMapping(value = "select/{id}")
 @SentinelResource(value = "select",fallback = "ErrorFallback")
 public CommonResult getid(@PathVariable Long id){

  if(id>3) {
  throw new NullPointerException(id+"沒有記錄");
  }else {
  return restTemplate.getForObject(URL + "/select/" + id,CommonResult.class);
  }

 }

fallback 處理方法

public CommonResult ErrorFallback(@PathVariable Long id,Throwable e){

 return new CommonResult<>(500,"不好意,沒有此記錄");
 }

處理結果

在這裡插入圖片描述

blockHandler 處理sentinel配置異常 java的異常無法處理

@SentinelResource(value = "select",blockHandler = "ErrorFallback")

 public CommonResult ErrorFallback(@PathVariable Long id,BlockException e){

 return new CommonResult<>(500,"不好意,沒有此記錄"+e.getMessage());
 }

測試
這設定的是異常比例 異常達到百分之30進行熔斷

在這裡插入圖片描述
在這裡插入圖片描述

在這裡插入圖片描述

兩個註解同時用

 @SentinelResource(value = "select",blockHandler = "ErrorFallback",fallback = "ErrorFallback1")
public CommonResult ErrorFallback1(@PathVariable Long id,"fallback:不好意,沒有此記錄"+e.getMessage());
 }
 public CommonResult ErrorFallback(@PathVariable Long id,"blockHandler:不好意,沒有此記錄"+e.getMessage());
 }

在這裡插入圖片描述

在這裡插入圖片描述

但是 要是blockHandler 和fallback 同時配置則被限流降級丟擲異常BlockException 處理

exceptionsToIgnore 
 @SentinelResource(value = "select",fallback = "ErrorFallback1",exceptionsToIgnore = {IllegalAccessException.class})
blockHandlerClass=定義返回統一返回方法.class

業務

@GetMapping(value = "select/test")
 @SentinelResource(value = "test",blockHandlerClass= MySentinel.class,blockHandler = "a")
 public String test(@RequestParam(value = "a",required = false) Integer b){

 return "我是:Sentinel";

 }

熔斷降級

package com.tang.cloud.mysentinel;

import com.alibaba.csp.sentinel.slots.block.BlockException;
import jdk.nashorn.internal.ir.Block;
import org.bouncycastle.crypto.engines.BlowfishEngine;
import org.springframework.web.bind.annotation.RequestParam;

/**
 * 統一返回降級處理
 */
public class MySentinel {

 //返回的的型別和呼叫的方法的型別一致,引數的型別和個數相同
 public static String a(@RequestParam(value = "a",required = false) Integer b,BlockException excep){

 return "我在在另一個類中定義的方法";
 }
 }

到此這篇關於SpringCloud-Alibaba-Sentinel服務降級熱點限流服務熔斷的文章就介紹到這了,更多相關SpringCloud-Alibaba-Sentinel-服務降級內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!