天天看點

SpringCloud Alibaba Sentinel(二)流控規則降級規則Sentinel熱點規則Sentinel系統配置@SentinelResource注解

Sentinel限流

  • 流控規則
    • 基本介紹
    • 流控模式
    • 流控效果
    • 代碼示範
      • 流控模式
        • 直接(預設)
        • 關聯
        • 鍊路
      • 流控效果
      • 直接
      • 預熱
      • 排隊等待
  • 降級規則
    • 名詞介紹
      • RT(平均響應時間,秒級)
      • 異常比例(秒級)
      • 異常數(分鐘級)
    • 概念
    • 降級政策實戰
      • RT
      • 異常比例
      • 異常數
  • Sentinel熱點規則
    • 什麼是熱點資料
    • 兜底的方法
    • 配置
    • 參數例外項
    • 結語
  • Sentinel系統配置
  • @SentinelResource注解
    • 問題
    • 客戶自定義限流處理邏輯
    • 更多注解屬性說明

流控規則

基本介紹

SpringCloud Alibaba Sentinel(二)流控規則降級規則Sentinel熱點規則Sentinel系統配置@SentinelResource注解

字段說明

資源名:唯一名稱,預設請求路徑

針對來源:Sentinel可以針對調用者進行限流,填寫微服務名,預設default(不區分來源)

門檻值類型 / 單機門檻值

QPS:(每秒鐘的請求數量):但調用該API的QPS達到門檻值的時候,進行限流

線程數:當調用該API的線程數達到門檻值的時候,進行限流

是否叢集:不需要叢集

流控模式

  • 直接:api都達到限流條件時,直接限流
  • 關聯:當關聯的資源達到門檻值,就限流自己
  • 鍊路:隻記錄指定鍊路上的流量(指定資源從入口資源進來的流量,如果達到門檻值,就進行限流)【API級别的針對來源】

流控效果

  • 快速失敗:直接失敗,抛異常
  • Warm UP:根據codeFactory(冷加載因子,預設3),從門檻值/CodeFactor,經過預熱時長,才達到設定的QPS門檻值
  • 排隊等待:勻速排隊,讓請求以勻速的速度通過,門檻值類型必須設定QPS,否則無效

代碼示範

流控模式

直接(預設)

我們給testA增加流控

SpringCloud Alibaba Sentinel(二)流控規則降級規則Sentinel熱點規則Sentinel系統配置@SentinelResource注解
SpringCloud Alibaba Sentinel(二)流控規則降級規則Sentinel熱點規則Sentinel系統配置@SentinelResource注解
SpringCloud Alibaba Sentinel(二)流控規則降級規則Sentinel熱點規則Sentinel系統配置@SentinelResource注解

然後我們請求

http://localhost:8401/testA

,就會出現失敗,被限流,快速失敗

SpringCloud Alibaba Sentinel(二)流控規則降級規則Sentinel熱點規則Sentinel系統配置@SentinelResource注解

思考:

直接調用的是預設報錯資訊,能否有我們的後續處理,比如更加友好的提示,類似有hystrix的fallback方法

線程數

這裡的線程數表示一次隻有一個線程進行業務請求,目前出現請求無法響應的時候,會直接報錯,例如,在方法的内部增加一個睡眠,那麼後面來的就會失敗

@GetMapping("/testD")

    public String testD()

    {

        try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }

        return "------testD";

    }

           

關聯

當關聯的資源達到門檻值時,就限流自己

當與A關聯的資源B達到門檻值後,就限流A自己,B惹事,A挂了

場景:支付接口達到門檻值後,就限流下訂單的接口

設定:

當關聯資源 /testB的QPS達到門檻值超過1時,就限流/testA的Rest通路位址,當關聯資源達到門檻值後,限制配置好的資源名

SpringCloud Alibaba Sentinel(二)流控規則降級規則Sentinel熱點規則Sentinel系統配置@SentinelResource注解

這個使用我們利用postman模拟并發密集通路

testB

首先我們需要使用postman,建立一個請求

SpringCloud Alibaba Sentinel(二)流控規則降級規則Sentinel熱點規則Sentinel系統配置@SentinelResource注解

同時将請求儲存在 Collection中

然後點選箭頭,選中接口,選擇run

SpringCloud Alibaba Sentinel(二)流控規則降級規則Sentinel熱點規則Sentinel系統配置@SentinelResource注解
SpringCloud Alibaba Sentinel(二)流控規則降級規則Sentinel熱點規則Sentinel系統配置@SentinelResource注解

點選運作,大批量線程高并發通路B,導緻A失效了,同時我們點選通路

http://localhost:8401/testA

,結果發現,我們的A已經挂了

SpringCloud Alibaba Sentinel(二)流控規則降級規則Sentinel熱點規則Sentinel系統配置@SentinelResource注解

在測試A接口

SpringCloud Alibaba Sentinel(二)流控規則降級規則Sentinel熱點規則Sentinel系統配置@SentinelResource注解

這就是我們的關聯限流

鍊路

多個請求調用了同一個微服務

流控效果

直接

快速失敗,預設的流控處理

直接失敗,抛出異常:Blocked by Sentinel(Flow limiting)

預熱

系統最怕的就是出現,平時通路是0,然後突然一瞬間來了10W的QPS

公式:門檻值 除以 clodFactor(預設值為3),經過預熱時長後,才會達到門檻值

Warm Up方式,即預熱/冷啟動方式,當系統長期處于低水位的情況下,當流量突然增加時,直接把系統拉升到高水位可能會瞬間把系統壓垮。通過冷啟動,讓通過的流量緩慢增加,在一定時間内逐漸增加到門檻值,給冷系統一個預熱的時間,避免冷系統被壓垮。通常冷啟動的過程系統允許的QPS曲線如下圖所示

SpringCloud Alibaba Sentinel(二)流控規則降級規則Sentinel熱點規則Sentinel系統配置@SentinelResource注解

預設clodFactor為3,即請求QPS從threshold / 3開始,經預熱時長逐漸提升至設定的QPS門檻值

SpringCloud Alibaba Sentinel(二)流控規則降級規則Sentinel熱點規則Sentinel系統配置@SentinelResource注解

假設這個系統的QPS是10,那麼最開始系統能夠接受的 QPS = 10 / 3 = 3,然後從3逐漸在5秒内提升到10

應用場景:

秒殺系統在開啟的瞬間,會有很多流量上來,很可能把系統打死,預熱的方式就是為了保護系統,可能慢慢的把流量放進來,慢慢的把門檻值增長到設定的門檻值。

SpringCloud Alibaba Sentinel(二)流控規則降級規則Sentinel熱點規則Sentinel系統配置@SentinelResource注解

排隊等待

大家均速排隊,讓請求以均勻的速度通過,門檻值類型必須設定成QPS,否則無效

均速排隊方式必須嚴格控制請求通過的間隔時間,也即讓請求以勻速的速度通過,對應的是漏桶算法。

SpringCloud Alibaba Sentinel(二)流控規則降級規則Sentinel熱點規則Sentinel系統配置@SentinelResource注解

這種方式主要用于處理間隔性突發的流量,例如消息隊列,想象一下這樣的場景,在某一秒有大量的請求到來,而接下來的幾秒處于空閑狀态,我們系統系統能夠接下來的空閑期間逐漸處理這些請求,而不是在第一秒直接拒絕多餘的請求。

設定含義:/testA 每秒1次請求,超過的話,就排隊等待,等待時間超過20000毫秒

SpringCloud Alibaba Sentinel(二)流控規則降級規則Sentinel熱點規則Sentinel系統配置@SentinelResource注解

降級規則

名詞介紹

SpringCloud Alibaba Sentinel(二)流控規則降級規則Sentinel熱點規則Sentinel系統配置@SentinelResource注解

RT(平均響應時間,秒級)

  • 平均響應時間,超過門檻值 且 時間視窗内通過的請求 >= 5,兩個條件同時滿足後出發降級
  • 視窗期過後,關閉斷路器
  • RT最大4900(更大的需要通過 -Dcsp.sentinel.staticstic.max.rt=XXXXX才能生效)

異常比例(秒級)

QPA >= 5 且異常比例(秒級)超過門檻值時,觸發降級;時間視窗結束後,關閉降級

異常數(分鐘級)

異常數(分鐘統計)超過門檻值時,觸發降級,時間視窗結束後,關閉降級

概念

Sentinel熔斷降級會在調用鍊路中某個資源出現不穩定狀态時(例如調用逾時或異常異常比例升高),對這個資源的調用進行限制,讓請求快速失敗,避免影響到其它的資源而導緻級聯錯誤。

當資源被降級後,在接下來的降級時間視窗之内,對該資源的調用都進行自動熔斷(預設行為是抛出DegradeException)

Sentinel的斷路器是沒有半開狀态

半開的狀态,系統自動去檢測是否請求有異常,沒有異常就關閉斷路器恢複使用,有異常則繼續打開斷路器不可用,具體可以參考hystrix

SpringCloud Alibaba Sentinel(二)流控規則降級規則Sentinel熱點規則Sentinel系統配置@SentinelResource注解

降級政策實戰

RT

平均響應時間 (

DEGRADE_GRADE_RT

):當 1s 内持續進入 N 個請求,對應時刻的平均響應時間(秒級)均超過門檻值(

count

,以 ms 為機關),那麼在接下的時間視窗(

DegradeRule

中的

timeWindow

,以 s 為機關)之内,對這個方法的調用都會自動地熔斷(抛出

DegradeException

)。注意 Sentinel 預設統計的 RT 上限是 4900 ms,超出此門檻值的都會算作 4900 ms,若需要變更此上限可以通過啟動配置項

-Dcsp.sentinel.statistic.max.rt=xxx

來配置。

SpringCloud Alibaba Sentinel(二)流控規則降級規則Sentinel熱點規則Sentinel系統配置@SentinelResource注解

代碼測試

@GetMapping("/testD")

    public String testD()

    {

        try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }

        log.info("testD 異常比例");

        return "------testD";

    }

           

然後使用Jmeter壓力測試工具進行測試

SpringCloud Alibaba Sentinel(二)流控規則降級規則Sentinel熱點規則Sentinel系統配置@SentinelResource注解

按照上述操作,永遠1秒種打進來10個線程,大于5個了,調用tesetD,我們希望200毫秒内處理完本次任務,如果200毫秒沒有處理完,在未來的1秒的時間視窗内,斷路器打開(保險絲跳閘)微服務不可用,保險絲跳閘斷電

Blocked by Sentinel (flow limiting)

           
SpringCloud Alibaba Sentinel(二)流控規則降級規則Sentinel熱點規則Sentinel系統配置@SentinelResource注解

後續我們停止使用jmeter,沒有那麼大的通路量了,斷路器關閉(保險絲恢複),微服務恢複OK

異常比例

異常比例 (

DEGRADE_GRADE_EXCEPTION_RATIO

):當資源的每秒請求量 >= N(可配置),并且每秒異常總數占通過量的比值超過門檻值(

DegradeRule

中的

count

)之後,資源進入降級狀态,即在接下的時間視窗(

DegradeRule

中的

timeWindow

,以 s 為機關)之内,對這個方法的調用都會自動地傳回。異常比率的門檻值範圍是

[0.0, 1.0]

,代表 0% - 100%。

SpringCloud Alibaba Sentinel(二)流控規則降級規則Sentinel熱點規則Sentinel系統配置@SentinelResource注解

單獨通路一次,必然來一次報錯一次,開啟jmeter後,直接高并發發送請求,多次調用達到我們的配置條件了,斷路器開啟(保險絲跳閘),微服務不可用,不在報錯,而是服務降級了

SpringCloud Alibaba Sentinel(二)流控規則降級規則Sentinel熱點規則Sentinel系統配置@SentinelResource注解

設定3秒内,如果請求百分50出錯,那麼就會熔斷

SpringCloud Alibaba Sentinel(二)流控規則降級規則Sentinel熱點規則Sentinel系統配置@SentinelResource注解

我們用jmeter每秒發送10次請求,3秒後,再次調用

localhost:8401/testD

出現服務降級

SpringCloud Alibaba Sentinel(二)流控規則降級規則Sentinel熱點規則Sentinel系統配置@SentinelResource注解

異常數

異常數 (

DEGRADE_GRADE_EXCEPTION_COUNT

):當資源近 1 分鐘的異常數目超過門檻值之後會進行熔斷。注意由于統計時間視窗是分鐘級别的,若

timeWindow

小于 60s,則結束熔斷狀态後仍可能再進入熔斷狀态

時間視窗一定要大于等于60秒

異常數是按分鐘來統計的

SpringCloud Alibaba Sentinel(二)流控規則降級規則Sentinel熱點規則Sentinel系統配置@SentinelResource注解

下面設定是,一分鐘内出現5次,則熔斷

SpringCloud Alibaba Sentinel(二)流控規則降級規則Sentinel熱點規則Sentinel系統配置@SentinelResource注解

首先我們再次通路

http://localhost:8401/testE

,第一次通路絕對報錯,因為除數不能為0,我們看到error視窗,但是達到5次報錯後,進入熔斷後的降級

Sentinel熱點規則

什麼是熱點資料

Github文檔傳送門

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

商品 ID 為參數,統計一段時間内最常購買的商品 ID 并進行限制

使用者 ID 為參數,針對一段時間内頻繁通路的使用者 ID 進行限制

熱點參數限流會統計傳入參數中的熱點參數,并根據配置的限流門檻值與模式,對包含熱點參數的資源調用進行限流。熱點參數限流可以看做是一種特殊的流量控制,僅對包含熱點參數的資源調用生效。

SpringCloud Alibaba Sentinel(二)流控規則降級規則Sentinel熱點規則Sentinel系統配置@SentinelResource注解

Sentinel 利用 LRU 政策統計最近最常通路的熱點參數,結合令牌桶算法來進行參數級别的流控。熱點參數限流支援叢集模式。

兜底的方法

分為系統預設的和客戶自定義的,兩種,之前的case中,限流出現問題了,都用sentinel系統預設的提示:Blocked By Sentinel,我們能不能自定義,類似于hystrix,某個方法出現問題了,就找到對應的兜底降級方法。

@HystrixCommand

@SentinelResource

配置

@SentinelResource的value,就是我們的資源名,也就是對哪個方法配置熱點規則

@GetMapping("/testHotKey")

    @SentinelResource(value = "testHotKey",blockHandler = "deal_testHotKey")

    public String testHotKey(@RequestParam(value = "p1",required = false) String p1,

                             @RequestParam(value = "p2",required = false) String p2)

    {

        //int age = 10/0;

        return "------testHotKey";

    }

    

    // 和上面的參數一樣,不錯需要加入 BlockException

    public String deal_testHotKey (String p1, String p2, BlockException exception)

    {

        return "------deal_testHotKey,o(╥﹏╥)o";  //  兜底的方法

    }

           

我們對參數0,設定熱點key進行限流

SpringCloud Alibaba Sentinel(二)流控規則降級規則Sentinel熱點規則Sentinel系統配置@SentinelResource注解

配置完成後

SpringCloud Alibaba Sentinel(二)流控規則降級規則Sentinel熱點規則Sentinel系統配置@SentinelResource注解

當我們不斷的請求時候,也就是以第一個參數為目标,請求接口,我們會發現多次請求後

http://localhost:8401/testHotKey?p1=a

           

就會出現以下的兜底錯誤

------deal_testHotKey,o(╥﹏╥)o

           

這是因為我們針對第一個參數進行了限制,當我們QPS超過1的時候,就會觸發兜底的錯誤

假設我們請求的接口是:

http://localhost:8401/testHotKey?p2=a

,我們會發現他就沒有進行限流

SpringCloud Alibaba Sentinel(二)流控規則降級規則Sentinel熱點規則Sentinel系統配置@SentinelResource注解

參數例外項

上述案例示範了第一個參數p1,當QPS超過1秒1次點選,馬上被限流

  • 普通:超過一秒1個後,達到門檻值1後馬上被限流
  • 我們期望p1參數當它達到某個特殊值時,它的限流值和平時不一樣
  • 特例:假設當p1的值等于5時,它的門檻值可以達到200
  • 一句話說:當key為特殊值的時候,不被限制
SpringCloud Alibaba Sentinel(二)流控規則降級規則Sentinel熱點規則Sentinel系統配置@SentinelResource注解

平時的時候,參數1的QPS是1,超過的時候被限流,但是有特殊值,比如5,那麼它的門檻值就是200

我們通過

http://localhost:8401/testHotKey?p1=5

一直重新整理,發現不會觸發兜底的方法,這就是參數例外項

熱點參數的注意點,參數必須是基本類型或者String

結語

@SentinelResource

處理的是Sentinel控制台配置的違規情況,有blockHandler方法配置的兜底處理

RuntimeException,如 int a = 10/0 ; 這個是java運作時抛出的異常,RuntimeException,@RentinelResource不管

也就是說:

@SentinelResource

主管配置出錯,運作出錯不管。

如果想要有配置出錯,和運作出錯的話,那麼可以設定 fallback

@GetMapping("/testHotKey")

    @SentinelResource(value = "testHotKey",blockHandler = "deal_testHotKey", fallback = "fallBack")

    public String testHotKey(@RequestParam(value = "p1",required = false) String p1,

                             @RequestParam(value = "p2",required = false) String p2)

    {

        //int age = 10/0;

        return "------testHotKey";

    }

           

Sentinel系統配置

Sentinel 系統自适應限流從整體次元對應用入口流量進行控制,結合應用的 Load、CPU 使用率、總體平均 RT、入口 QPS 和并發線程數等幾個次元的監控名額,通過自适應的流控政策,讓系統的入口流量和系統的負載達到一個平衡,讓系統盡可能跑在最大吞吐量的同時保證系統整體的穩定性。

系統保護規則是從應用級别的入口流量進行控制,從單台機器的 load、CPU 使用率、平均 RT、入口 QPS 和并發線程數等幾個次元監控應用名額,讓系統盡可能跑在最大吞吐量的同時保證系統整體的穩定性。

系統保護規則是應用整體次元的,而不是資源次元的,并且僅對入口流量生效。入口流量指的是進入應用的流量(

EntryType.IN

),比如 Web 服務或 Dubbo 服務端接收的請求,都屬于入口流量。

系統規則支援以下的模式:

  • Load 自适應(僅對 Linux/Unix-like 機器生效):系統的 load1 作為啟發名額,進行自适應系統保護。當系統 load1 超過設定的啟發值,且系統目前的并發線程數超過估算的系統容量時才會觸發系統保護(BBR 階段)。系統容量由系統的

    maxQps * minRt

    估算得出。設定參考值一般是

    CPU cores * 2.5

  • CPU usage(1.5.0+ 版本):當系統 CPU 使用率超過門檻值即觸發系統保護(取值範圍 0.0-1.0),比較靈敏。
  • 平均 RT:當單台機器上所有入口流量的平均 RT 達到門檻值即觸發系統保護,機關是毫秒。
  • 并發線程數:當單台機器上所有入口流量的并發線程數達到門檻值即觸發系統保護。
  • 入口 QPS:當單台機器上所有入口流量的 QPS 達到門檻值即觸發系統保護。
SpringCloud Alibaba Sentinel(二)流控規則降級規則Sentinel熱點規則Sentinel系統配置@SentinelResource注解

這樣相當于設定了全局的QPS過濾

@SentinelResource注解

按資源名稱限流 + 後續處理

按URL位址限流 + 後續處理

問題

  • 系統預設的,沒有展現我們自己的業務要求
  • 依照現有條件,我們自定義的處理方法又和業務代碼耦合在一塊,不直覺
  • 每個業務方法都添加一個兜底方法,那代碼膨脹加劇
  • 全局統一的處理方法沒有展現
  • 關閉8401,發現流控規則已經消失,說明這個是沒有持久化

客戶自定義限流處理邏輯

建立CustomerBlockHandler類用于自定義限流處理邏輯

public class CustomerBlockHandler

{

    public static CommonResult handlerException(BlockException exception)

    {

        return new CommonResult(4444,"按客戶自定義,global handlerException----1");

    }

    public static CommonResult handlerException2(BlockException exception)

    {

        return new CommonResult(4444,"按客戶自定義,global handlerException----2");

    }

}

           

那麼我們在使用的時候,就可以首先指定是哪個類,哪個方法

@GetMapping("/rateLimit/customerBlockHandler")

    @SentinelResource(value = "customerBlockHandler",

            blockHandlerClass = CustomerBlockHandler.class,

            blockHandler = "handlerException2")

    public CommonResult customerBlockHandler()

    {

        return new CommonResult(200,"按客戶自定義",new Payment(2020L,"serial003"));

    }

           
SpringCloud Alibaba Sentinel(二)流控規則降級規則Sentinel熱點規則Sentinel系統配置@SentinelResource注解

更多注解屬性說明

所有的代碼都要用try - catch - finally 進行處理

sentinel主要有三個核心API

  • Sphu定義資源
  • Tracer定義統計
  • ContextUtil定義了上下文