SpringCloud Alibaba Sentinel 限流詳解

點贊再看成畦,養(yǎng)成習(xí)慣,微信搜索【牧小農(nóng)】關(guān)注我獲取更多資訊罩驻,風(fēng)里雨里穗酥,小農(nóng)等你,很高興能夠成為你的朋友惠遏。
項目源碼地址:公眾號回復(fù) sentinel砾跃,即可免費獲取源碼

熔斷規(guī)則

在上一篇文章中我們講解了流控規(guī)則的使用和介紹Sentinel流控規(guī)則,今天我們給大家講解sentinel更多樣化的講解以及流量控制爽哎。

官方文檔:https://sentinelguard.io/zh-cn/docs/circuit-breaking.html

在面對調(diào)用鏈路中不穩(wěn)定的資源如何保證高可用蜓席?在微服務(wù)中一個服務(wù)通常會調(diào)用其他的模塊,可能是服務(wù)內(nèi)的某個應(yīng)用也有可能是另外的一個遠程服務(wù)课锌,數(shù)據(jù)庫或者其他API調(diào)用厨内。比如我們在支付的時候會調(diào)用(某付寶、某信渺贤、某聯(lián))提供的API雏胃,在查詢訂單我們會調(diào)用數(shù)據(jù)庫連接,這些依賴的服務(wù)有可能會存在系統(tǒng)不穩(wěn)定的情況志鞍,如果依賴的服務(wù)出現(xiàn)了不穩(wěn)定的情況瞭亮,請求響應(yīng)時間過長,線程資源產(chǎn)生堆積固棚,可能最終會耗盡服務(wù)的資源统翩,導(dǎo)致服務(wù)變的不可用,這個時候 熔斷降級 是保證服務(wù)高可用的重要措施之一此洲。

image.png

如今的微服務(wù)都是分布式厂汗,有很多服務(wù)組成,不同服務(wù)之間互相調(diào)用呜师,有著比較復(fù)雜的調(diào)用鏈路娶桦,在上面我們只是模擬繪畫了支付操作,在實際的鏈路調(diào)用過程中會有著放大效果,如果某一環(huán)不穩(wěn)定衷畦,可能會形成 蝴蝶效應(yīng) 最終導(dǎo)致整個鏈路響應(yīng)時間過長栗涂,甚至不可用,所以如果當我們的服務(wù)出現(xiàn) 不穩(wěn)定且沒有強依賴服務(wù) 調(diào)用的時祈争,可以進行熔斷降級斤程,暫時限制不穩(wěn)定的調(diào)用,避免影響整體服務(wù)铛嘱。

image.png

熔斷策略:

sentinel提供了三種熔斷策略

image.png
  • 慢調(diào)用比例: 選擇以慢調(diào)用比例作為閾值暖释,需要設(shè)置允許的慢調(diào)用RT(最大響應(yīng)時間),如果請求響應(yīng)時間大于該值則認為慢調(diào)用墨吓,當統(tǒng)計時長內(nèi)請求數(shù) 大于 最小請求數(shù)球匕,且慢調(diào)用比例大于閾值闻牡,在熔斷時長內(nèi)的請求會被自動熔斷只盹,超過熔斷時長進入半恢復(fù)狀態(tài)(HALF_OPEN)胁塞,如果下一個請求響應(yīng)時間 小于 慢調(diào)用比例RT結(jié)束熔斷朗儒,否則再次熔斷腊尚。

  • 異常比例: 當統(tǒng)計時長內(nèi)請求數(shù) 大于 最小請求數(shù)机错,且異常比例大于設(shè)定的閾值枪眉,在熔斷時間內(nèi)請求自動熔斷狸驳,超過熔斷時長進入半恢復(fù)狀態(tài)(HALF_OPEN)乡摹,如果下一個請求成功役耕,結(jié)束熔斷,否則再次熔斷聪廉,異常比例閾值范圍(0.0-1.0)代表百分比瞬痘。

  • 異常數(shù): 當統(tǒng)計時長內(nèi)異常數(shù) 大于 閾值,自動進行熔斷板熊,超過熔斷時長進入半恢復(fù)狀態(tài)(HALF_OPEN)框全,如果下一個請求成功,結(jié)束熔斷干签,否則再次熔斷津辩。

熔斷狀態(tài):

熔斷狀態(tài) 說明
OPEN 熔斷開啟,拒絕所有請求
HALF_OPEN 熔斷半開啟(恢復(fù)狀態(tài))容劳,如果接下來請求成功結(jié)束熔斷喘沿,否則繼續(xù)熔斷
CLOSE 熔斷關(guān)閉,請求通過

熱點參數(shù)規(guī)則的核心屬性:

屬性(Field) 說明 默認值
resource 資源名(規(guī)則的作用對象 ) 必填
grade 熔斷策略(支持慢調(diào)用比例/異常比例/異常數(shù)策略) 必填 慢調(diào)用比例
count 慢調(diào)用比例模式下為慢調(diào)用臨界 RT(超出該值計為慢調(diào)用)竭贩;異常比例/異常數(shù)模式下為對應(yīng)的閾值
timeWindow 熔斷時長蚜印,單位為 s
minRequestAmount 熔斷觸發(fā)的最小請求數(shù),請求數(shù)小于該值時即使異常比率超出閾值也不會熔斷(1.7.0 引入) 5
statIntervalMs 統(tǒng)計時長(單位為 ms)娶视,如 60*1000 代表分鐘級(1.8.0 引入) 1000 ms
slowRatioThreshold 慢調(diào)用比例閾值晒哄,僅慢調(diào)用比例模式有效(1.8.0 引入)

熔斷策略 - 慢調(diào)用比例

選擇以慢調(diào)用比例作為閾值,需要設(shè)置允許的慢調(diào)用RT(最大響應(yīng)時間)肪获,如果請求響應(yīng)時間大于該值則認為慢調(diào)用寝凌,當統(tǒng)計時長內(nèi)請求數(shù) 大于 最小請求數(shù),且慢調(diào)用比例大于閾值孝赫,在熔斷時長內(nèi)的請求會被自動熔斷较木,超過熔斷時長進入半恢復(fù)狀態(tài)(HALF_OPEN),如果下一個請求響應(yīng)時間 小于 慢調(diào)用比例RT結(jié)束熔斷青柄,否則再次熔斷伐债。

image.png

如果我們一秒鐘請求的數(shù)量大于5且RT(最大響應(yīng)時間)大于我們設(shè)置的比例閾值的時候,觸發(fā)熔斷策略致开,比如我們有8個請求在一秒中進來峰锁,有5個慢調(diào)用,比例閾值設(shè)置為 0.1双戳,這個時候我們滿足(QPS > 5 且 RT > 比例閾值)虹蒋,進入下一步熔斷策略,觸發(fā)熔斷器飒货。

熔斷器的內(nèi)部使用的是斷路器魄衅,這個好比我們做核酸,本來一棟一棟下去做塘辅,如果服務(wù)或者檢測機器蹦了晃虫,通知你暫時不要下來,當機器恢復(fù)了扣墩,再通知你下來做哲银,這個就類似我們的斷路器。

image.png

案例演示:

    @GetMapping("/fuse")
    public String fuse(){
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "hello fuse";
    }

設(shè)置我們的熔斷策略沮榜,如果QPS>5請求RT>250且大于比例閾值觸發(fā)熔斷

image.png

通過JMeter測試盘榨,1秒鐘發(fā)起10個線程請求,此時就會觸發(fā)熔斷效果蟆融,停止測試以后草巡,10秒鐘恢復(fù)正常

image.png

當我們啟動線程之后,再去訪問fuse接口型酥,可以看到被熔斷了山憨,那么當我們停止線程之后,十秒之后去訪問弥喉,就可以正常訪問

image.png

熔斷策略 - 異常比例

當統(tǒng)計時長內(nèi)請求數(shù) 大于 最小請求數(shù)郁竟,且異常比例大于設(shè)定的閾值,在熔斷時間內(nèi)請求自動熔斷由境,超過熔斷時長進入半恢復(fù)狀態(tài)(HALF_OPEN)棚亩,如果下一個請求成功蓖议,結(jié)束熔斷,否則再次熔斷讥蟆,異常比例閾值范圍(0.0-1.0)代表百分比勒虾。異常降級僅僅只針對業(yè)務(wù)異常,對于sentinel本身的異常不生效瘸彤。

image.png

測試:

    @GetMapping("/exptoin")
    public String exptoin(Integer id){
        if(id != null && id > 1){
            throw new RuntimeException("異常比例測試");
        }
        return "exptoin test";
    }
image.png

接下來我們用JMeter進行測試修然,設(shè)置Http請求地址:http://localhost:8006/exptoin?id=5 當啟動JMeter的時候,會觸發(fā)熔斷质况,這個時候我們1秒鐘發(fā)送10個請求超過了最小請求數(shù)愕宋,同事超過了閾值,滿足兩個條件结榄,當熔斷時間結(jié)束 以后恢復(fù)正常

image.png

熔斷策略 - 異常數(shù)

當統(tǒng)計時長內(nèi)異常數(shù) 大于 閾值中贝,自動進行熔斷,超過熔斷時長進入半恢復(fù)狀態(tài)(HALF_OPEN)臼朗,如果下一個請求成功雄妥,結(jié)束熔斷,否則再次熔斷依溯。

image.png

測試代碼:

    @GetMapping("/exptoin/num")
    public String exptoinNum(Integer id){
        if(id != null && id > 1){
            throw new RuntimeException("異常數(shù)測試");
        }
        return "exptoinNum test";
    }

設(shè)置異常數(shù)策略老厌,當1秒鐘內(nèi)請求超過5并且異常數(shù)大約5個的時候觸發(fā)熔斷

image.png
image.png
image.png

熱點規(guī)則

官網(wǎng)文檔:https://sentinelguard.io/zh-cn/docs/parameter-flow-control.html

什么是熱點規(guī)則?熱點我們很好理解黎炉,就是很火的東西在程序中可以理解成頻繁訪問的數(shù)據(jù)枝秤,那么有時候我們系統(tǒng)通緝你某個熱點數(shù)據(jù)中訪問頻次最高的 前幾個數(shù)據(jù)對其進行限制訪問。

例如在秒殺系統(tǒng)中慷嗜,某一款商品或者某幾款商品淀弹,要定點秒殺,我們可以以商品ID為參數(shù)庆械,在一定時間內(nèi)對其進行限流

又或者如果某一個用戶頻繁的去訪問我們系統(tǒng)薇溃,我們也可以針對于用戶ID或者IP進行限制。

熱點規(guī)則會統(tǒng)計入?yún)?shù)中的熱點數(shù)據(jù)缭乘,根據(jù)配置的限流閾值和模式沐序,對啟動的熱點數(shù)據(jù)進行限流也就是流量控制。

image.png

在上圖中我們攜帶了 是三個參數(shù)(axb\abc\xs)等堕绩,我們在sentinel中設(shè)置熱點限流策幼,我們設(shè)置的QPS為5,注意:該模式只支持QPS限制奴紧,如果我們的axb參數(shù)特姐,命中了我們的規(guī)則,那么該請求攜帶的參數(shù)就會被限流黍氮。

image.png

在使用熱點規(guī)則的時候唐含,我們需要配合對應(yīng)的@SentinelResource注解進行使用浅浮,才能夠達到更加細粒度的流控規(guī)則。

@SentinelResource

  • value:代表資源名稱捷枯,必填脑题,通過name找到對應(yīng)的規(guī)則
  • blockHandler: blockHandler 對應(yīng)處理 BlockException 的方法名稱,可選項铜靶,訪問范圍為public,返回類型需要和原方法匹配他炊,并且在最后一需要添加BlockException類型的參數(shù)
image.png

測試代碼:

    @GetMapping("/hotTest")
    @SentinelResource(value = "hotTest")
    public String testHotKey(@RequestParam(value = "v1",required = false) String v1,
                             @RequestParam(value = "v2",required = false)String v2){
        return "熱點規(guī)則 -  熱點:";
    }
image.png

在這里我們要注意争剿,我們需要配置的是不帶斜杠的資源名稱,這個才是我們需要配置的項目

image.png

這個時候我們傳入?yún)?shù) http://localhost:8006/hotTest?v1痊末,不停的刷新瀏覽器蚕苇,這個時候會超過閾值,那么下面就會出現(xiàn)限流

image.png

但是凿叠,這個報錯信息不是很友好涩笤,一般人根本不知道啥意思,我們可以使用@SentinelResource注解提供的另外一個參數(shù)blockHandler盒件,這個參數(shù)是可以指定當出現(xiàn)異常時的處理方法蹬碧,操作如下:

    @GetMapping("/hotTest")
    @SentinelResource(value = "hotTest",blockHandler = "handler_hot")
    public String testHotKey(@RequestParam(value = "v1",required = false) String v1,
                             @RequestParam(value = "v2",required = false)String v2){

        if("5".equals(v1)){
            throw new RuntimeException("報告有bug!!!");
        }
        return "熱點規(guī)則 -  熱點:";
    }
    
     //處理異常方法,方法簽名要和對應(yīng)的接口方法保持一致
    public String handler_hot(String v1, String v2, BlockException exception){
        return "請求過于頻繁炒刁,請稍后再試.....";
    }

重新添加熱點規(guī)則后恩沽,再去頻繁的去訪問,效果如下:

image.png

例外項數(shù)目

image.png

熱點規(guī)則除了上述的基礎(chǔ)使用外翔始,還有例外項的操作罗心,例外項參數(shù)可以達到更加細粒度的控制,比如我們在當前的案例中城瞎,目前v1參數(shù)在訪問時超過閾值則會被限流渤闷,當時如果我們想通過參數(shù)v1等于具體的值的時候,來出發(fā)不同的流控效果時脖镀,改怎么操作呢飒箭?

比如我想要讓v1等于2的時候,閾值達到50蜒灰,其他的規(guī)則走上面的規(guī)則补憾。

image.png

如果當前v1的值為2的時候,會走例外項里面的設(shè)置卷员,也就是50的閾值盈匾,如果不是2會走普通的閾值規(guī)則,通過下圖我們可以看到如果為2的值毕骡,無論我們點擊多少次削饵,都不會提示我們請求過于頻繁岩瘦。

image.png

系統(tǒng)規(guī)則

sentinel系統(tǒng)自適應(yīng)限流是從整體維度對應(yīng)用入口流量進行控制,結(jié)合應(yīng)用的 load窿撬、CPU使用率启昧、總體平均RT、入口QPS和并發(fā)線程數(shù)等幾個維度的監(jiān)控指標劈伴,通過自適應(yīng)的流控策略密末,來讓系統(tǒng)入口流量和系統(tǒng)的負載達到一個平衡,讓系統(tǒng)盡可能的在面對高并發(fā)訪問的同時保證系統(tǒng)整體的穩(wěn)定跛璧。

系統(tǒng)保護是應(yīng)用整體严里,所以不具備更細粒度的操作,只針對于入口流量有效追城。

image.png

系統(tǒng)規(guī)則支持的模式:

image.png
  • LOAD自適應(yīng): 針對于linxu/unix 機器有效刹碾,系統(tǒng)load(一分鐘平均負載)作為啟發(fā)指標,進行自適應(yīng)系統(tǒng)保護座柱。
  • RT:單臺機器上所有的入口流量平均RT達到閾值時迷帜,觸發(fā)系統(tǒng)保護,單位為毫秒
  • 線程數(shù): 單臺機器上所有入口流量的并發(fā)線程數(shù)達到閾值觸發(fā)系統(tǒng)保護
  • 入口QPS: 單臺機器上所有入口流量的QPS達到閾值觸發(fā)系統(tǒng)保護
  • CPU 使用率: 當系統(tǒng)CPU使用率超過閾值時觸發(fā)系統(tǒng)保護(取值范圍:0.0 - 1.0)

演示:

通過入口QPS來進行測試色洞,直接設(shè)置規(guī)則


image.png

最后測試效果不管現(xiàn)在我們訪問那個接口只要超過閾值就會被限流


image.png

總結(jié)

到這里我們限流策略就講完了戏锹,其實并不復(fù)雜,我們需要了解其中每個規(guī)則如何使用火诸,效果是怎樣的景用,最好是自己動手試一試,會更有成就感惭蹂。

我是牧小農(nóng)伞插,怕什么真理無窮,進一步有進一步的歡喜盾碗,大家加油

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末媚污,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子廷雅,更是在濱河造成了極大的恐慌耗美,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,539評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件航缀,死亡現(xiàn)場離奇詭異商架,居然都是意外死亡,警方通過查閱死者的電腦和手機芥玉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評論 3 396
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來灿巧,“玉大人赶袄,你說我怎么就攤上這事揽涮。” “怎么了饿肺?”我有些...
    開封第一講書人閱讀 165,871評論 0 356
  • 文/不壞的土叔 我叫張陵蒋困,是天一觀的道長。 經(jīng)常有香客問我敬辣,道長雪标,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,963評論 1 295
  • 正文 為了忘掉前任溉跃,我火速辦了婚禮村刨,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘喊积。我一直安慰自己,他們只是感情好玄妈,可當我...
    茶點故事閱讀 67,984評論 6 393
  • 文/花漫 我一把揭開白布乾吻。 她就那樣靜靜地躺著,像睡著了一般拟蜻。 火紅的嫁衣襯著肌膚如雪绎签。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,763評論 1 307
  • 那天酝锅,我揣著相機與錄音诡必,去河邊找鬼。 笑死搔扁,一個胖子當著我的面吹牛爸舒,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播稿蹲,決...
    沈念sama閱讀 40,468評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼扭勉,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了苛聘?” 一聲冷哼從身側(cè)響起涂炎,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎设哗,沒想到半個月后唱捣,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,850評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡网梢,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,002評論 3 338
  • 正文 我和宋清朗相戀三年震缭,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片战虏。...
    茶點故事閱讀 40,144評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡蛀序,死狀恐怖欢瞪,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情徐裸,我是刑警寧澤遣鼓,帶...
    沈念sama閱讀 35,823評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站重贺,受9級特大地震影響骑祟,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜气笙,卻給世界環(huán)境...
    茶點故事閱讀 41,483評論 3 331
  • 文/蒙蒙 一次企、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧潜圃,春花似錦缸棵、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至隧出,卻和暖如春踏志,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背胀瞪。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評論 1 272
  • 我被黑心中介騙來泰國打工针余, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人凄诞。 一個月前我還...
    沈念sama閱讀 48,415評論 3 373
  • 正文 我出身青樓圆雁,卻偏偏與公主長得像,于是被迫代替她去往敵國和親帆谍。 傳聞我的和親對象是個殘疾皇子摸柄,可洞房花燭夜當晚...
    茶點故事閱讀 45,092評論 2 355

推薦閱讀更多精彩內(nèi)容