SpringCloud Alibaba 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ù)高可用的重要措施之一。
如今的微服務(wù)都是分布式,有很多服務(wù)組成,不同服務(wù)之間互相調(diào)用,有著比較復(fù)雜的調(diào)用鏈路,在上面我們只是模擬繪畫了支付操作,在實際的鏈路調(diào)用過程中會有著放大效果,如果某一環(huán)不穩(wěn)定,可能會形成 蝴蝶效應(yīng) 最終導(dǎo)致整個鏈路響應(yīng)時間過長,甚至不可用,所以如果當(dāng)我們的服務(wù)出現(xiàn) 不穩(wěn)定且沒有強依賴服務(wù) 調(diào)用的時,可以進行熔斷降級,暫時限制不穩(wěn)定的調(diào)用,避免影響整體服務(wù)。
熔斷策略:
sentinel
提供了三種熔斷策略
-
慢調(diào)用比例: 選擇以慢調(diào)用比例作為閾值,需要設(shè)置允許的慢調(diào)用RT(最大響應(yīng)時間),如果請求響應(yīng)時間大于該值則認(rèn)為慢調(diào)用,當(dāng)統(tǒng)計時長內(nèi)請求數(shù) 大于 最小請求數(shù),且慢調(diào)用比例大于閾值,在熔斷時長內(nèi)的請求會被自動熔斷,超過熔斷時長進入半恢復(fù)狀態(tài)(HALF_OPEN),如果下一個請求響應(yīng)時間 小于 慢調(diào)用比例RT結(jié)束熔斷,否則再次熔斷。
-
異常比例: 當(dāng)統(tǒng)計時長內(nèi)請求數(shù) 大于 最小請求數(shù),且異常比例大于設(shè)定的閾值,在熔斷時間內(nèi)請求自動熔斷,超過熔斷時長進入半恢復(fù)狀態(tài)(HALF_OPEN),如果下一個請求成功,結(jié)束熔斷,否則再次熔斷,異常比例閾值范圍(0.0-1.0)代表百分比。
-
異常數(shù): 當(dāng)統(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) | 說明 | 默認(rèn)值 |
---|---|---|
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)時間大于該值則認(rèn)為慢調(diào)用,當(dāng)統(tǒng)計時長內(nèi)請求數(shù) 大于 最小請求數(shù),且慢調(diào)用比例大于閾值,在熔斷時長內(nèi)的請求會被自動熔斷,超過熔斷時長進入半恢復(fù)狀態(tài)(HALF_OPEN),如果下一個請求響應(yīng)時間 小于 慢調(diào)用比例RT結(jié)束熔斷,否則再次熔斷。
如果我們一秒鐘請求的數(shù)量大于5且RT(最大響應(yīng)時間)大于我們設(shè)置的比例閾值的時候,觸發(fā)熔斷策略,比如我們有8個請求在一秒中進來,有5個慢調(diào)用,比例閾值設(shè)置為 0.1,這個時候我們滿足(QPS > 5 且 RT > 比例閾值),進入下一步熔斷策略,觸發(fā)熔斷器。
熔斷器的內(nèi)部使用的是斷路器,這個好比我們做核酸,本來一棟一棟下去做,如果服務(wù)或者檢測機器蹦了,通知你暫時不要下來,當(dāng)機器恢復(fù)了,再通知你下來做,這個就類似我們的斷路器。
案例演示:
@GetMapping("/fuse")
public String fuse(){
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "hello fuse";
}
設(shè)置我們的熔斷策略,如果QPS>5請求RT>250且大于比例閾值觸發(fā)熔斷
通過JMeter
測試,1秒鐘發(fā)起10個線程請求,此時就會觸發(fā)熔斷效果,停止測試以后,10秒鐘恢復(fù)正常
當(dāng)我們啟動線程之后,再去訪問fuse接口,可以看到被熔斷了,那么當(dāng)我們停止線程之后,十秒之后去訪問,就可以正常訪問
熔斷策略 - 異常比例
當(dāng)統(tǒng)計時長內(nèi)請求數(shù) 大于 最小請求數(shù),且異常比例大于設(shè)定的閾值,在熔斷時間內(nèi)請求自動熔斷,超過熔斷時長進入半恢復(fù)狀態(tài)(HALF_OPEN),如果下一個請求成功,結(jié)束熔斷,否則再次熔斷,異常比例閾值范圍(0.0-1.0)代表百分比。異常降級僅僅只針對業(yè)務(wù)異常,對于sentinel
本身的異常不生效。
測試:
@GetMapping("/exptoin")
public String exptoin(Integer id){
if(id != null && id > 1){
throw new RuntimeException("異常比例測試");
}
return "exptoin test";
}
接下來我們用JMeter進行測試,設(shè)置Http請求地址:http://localhost:8006/exptoin?id=5
當(dāng)啟動JMeter的時候,會觸發(fā)熔斷,這個時候我們1秒鐘發(fā)送10個請求超過了最小請求數(shù),同事超過了閾值,滿足兩個條件,當(dāng)熔斷時間結(jié)束 以后恢復(fù)正常
熔斷策略 - 異常數(shù)
當(dāng)統(tǒng)計時長內(nèi)異常數(shù) 大于 閾值,自動進行熔斷,超過熔斷時長進入半恢復(fù)狀態(tài)(HALF_OPEN),如果下一個請求成功,結(jié)束熔斷,否則再次熔斷。
測試代碼:
@GetMapping("/exptoin/num")
public String exptoinNum(Integer id){
if(id != null && id > 1){
throw new RuntimeException("異常數(shù)測試");
}
return "exptoinNum test";
}
設(shè)置異常數(shù)策略,當(dāng)1秒鐘內(nèi)請求超過5并且異常數(shù)大約5個的時候觸發(fā)熔斷
熱點規(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ù)進行限流也就是流量控制。
在上圖中我們攜帶了 是三個參數(shù)(axb\abc\xs)等,我們在sentinel
中設(shè)置熱點限流,我們設(shè)置的QPS為5,注意:該模式只支持QPS限制,如果我們的axb參數(shù),命中了我們的規(guī)則,那么該請求攜帶的參數(shù)就會被限流。
在使用熱點規(guī)則的時候,我們需要配合對應(yīng)的@SentinelResource
注解進行使用,才能夠達到更加細粒度的流控規(guī)則。
@SentinelResource
- value:代表資源名稱,必填,通過name找到對應(yīng)的規(guī)則
- blockHandler: blockHandler 對應(yīng)處理 BlockException 的方法名稱,可選項,訪問范圍為public,返回類型需要和原方法匹配,并且在最后一需要添加
BlockException
類型的參數(shù)
測試代碼:
@GetMapping("/hotTest")
@SentinelResource(value = "hotTest")
public String testHotKey(@RequestParam(value = "v1",required = false) String v1,
@RequestParam(value = "v2",required = false)String v2){
return "熱點規(guī)則 - 熱點:";
}
在這里我們要注意,我們需要配置的是不帶斜杠的資源名稱,這個才是我們需要配置的項目
這個時候我們傳入?yún)?shù) http://localhost:8006/hotTest?v1
,不停的刷新瀏覽器,這個時候會超過閾值,那么下面就會出現(xiàn)限流
但是,這個報錯信息不是很友好,一般人根本不知道啥意思,我們可以使用@SentinelResource
注解提供的另外一個參數(shù)blockHandler
,這個參數(shù)是可以指定當(dāng)出現(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ī)則后,再去頻繁的去訪問,效果如下:
例外項數(shù)目
熱點規(guī)則除了上述的基礎(chǔ)使用外,還有例外項的操作,例外項參數(shù)可以達到更加細粒度的控制,比如我們在當(dāng)前的案例中,目前v1參數(shù)在訪問時超過閾值則會被限流,當(dāng)時如果我們想通過參數(shù)v1等于具體的值的時候,來出發(fā)不同的流控效果時,改怎么操作呢?
比如我想要讓v1等于2的時候,閾值達到50,其他的規(guī)則走上面的規(guī)則。
如果當(dāng)前v1的值為2的時候,會走例外項里面的設(shè)置,也就是50的閾值,如果不是2會走普通的閾值規(guī)則,通過下圖我們可以看到如果為2的值,無論我們點擊多少次,都不會提示我們請求過于頻繁。
系統(tǒng)規(guī)則
sentinel
系統(tǒng)自適應(yīng)限流是從整體維度對應(yīng)用入口流量進行控制,結(jié)合應(yīng)用的 load、CPU使用率、總體平均RT、入口QPS和并發(fā)線程數(shù)等幾個維度的監(jiān)控指標(biāo),通過自適應(yīng)的流控策略,來讓系統(tǒng)入口流量和系統(tǒng)的負(fù)載達到一個平衡,讓系統(tǒng)盡可能的在面對高并發(fā)訪問的同時保證系統(tǒng)整體的穩(wěn)定。
系統(tǒng)保護是應(yīng)用整體,所以不具備更細粒度的操作,只針對于入口流量有效。
系統(tǒng)規(guī)則支持的模式:
- LOAD自適應(yīng): 針對于linxu/unix 機器有效,系統(tǒng)load(一分鐘平均負(fù)載)作為啟發(fā)指標(biāo),進行自適應(yīng)系統(tǒng)保護。
- RT:單臺機器上所有的入口流量平均RT達到閾值時,觸發(fā)系統(tǒng)保護,單位為毫秒
- 線程數(shù): 單臺機器上所有入口流量的并發(fā)線程數(shù)達到閾值觸發(fā)系統(tǒng)保護
- 入口QPS: 單臺機器上所有入口流量的QPS達到閾值觸發(fā)系統(tǒng)保護
- CPU 使用率: 當(dāng)系統(tǒng)CPU使用率超過閾值時觸發(fā)系統(tǒng)保護(取值范圍:0.0 - 1.0)
演示:
通過入口QPS來進行測試,直接設(shè)置規(guī)則
最后測試效果不管現(xiàn)在我們訪問那個接口只要超過閾值就會被限流
總結(jié)
到這里我們限流策略就講完了,其實并不復(fù)雜,我們需要了解其中每個規(guī)則如何使用,效果是怎樣的,最好是自己動手試一試,會更有成就感,如果覺得文章的內(nèi)容對你有幫助,記得點贊關(guān)注,你的支持是我創(chuàng)作的最大動力,感謝您的支持!
文章轉(zhuǎn)載自: https://muxiaonong.blog.csdn.net
公眾號:牧小農(nóng),微信掃碼關(guān)注或搜索公眾號名稱