所有代碼都在github上:https://github.com/demonruin/cloud2020/tree/master
一、流控規則 :流量限制控制規則
Sentinel-dashboard中的流控規則菜單項:
- 資源名:唯一名稱,默認請求路徑
- 針對來源: Sentine可以針對調用者進行限流,填寫微服務名,默認default (不區分來源)
- 閾值類型/單機閾值:
- QPS (每秒鐘的請求數量) :當調用該api的QPS達到閾值的時候,進行限流
- 線程數:當調用該api的線程數達到閾值的時候,進行限流
- 是否集羣:不需要集羣
- 流控模式:
- 直接: api達到限流條件時,直接限流
- 關聯:當關聯的資源達到閾值時,就限流自己
- 鏈路:只記錄指定鏈路上的流量(指定資源從入口資源進來的流量,如果達到閾值,就進行限流) [ api級別的針對來源]
- 流控效果:
- 快速失敗:直接失敗,拋異常
- Warm Up:根據codeFactor (冷加載因子,默認3)的值,從閾值/codeFactor, 經過預熱時長,才達到置的QPS閾值
- 排隊等待:勻速排隊,讓請求以勻速的速度通過,閾值類型必須設置爲QPS,否則無效
二、流控模式:
配置流控模式有兩種方法:
1、在簇點鏈路中找到對應的資源名(即訪問路徑---唯一的),然後操作添加 流控
2、在流控規則裏面 新增流控規則 填寫 資源名等配置,和1操作等同
下面對不同的模式進行測試:
1、default模式:
就是直接-->快速失敗模式 也即系統默認模式,進行測試設置,查看測試結果:設置default、QPS類型,單機閾值爲1(即1秒請求一次),流控模式爲直接、流控效果爲快速失敗。
測試結果:當每秒請求一次的時候,正常響應結果,當每秒請求次數超過一次的時候,會出現快速失敗結果Blocked by Sentinel (flow limiting),如圖下:
這種是直接調用默認的報錯方法,應該還會有自定義的fallback方法進行我們自己的後續處理,後續再講這部分~
當我們將閾值類型 改爲 線程數的時候,就沒有下面的流控效果配置了:
此時的意思和QPS就不太一樣了,
QPS是直接讓一波請求過來的時候只放一個進來,其他的就快速失敗;
而線程數設置是指接口就一個能進行處理請求,把請求全部放進來,等處理請求處理不過來的時候,就快速失敗。
測試:在testA接口中添加睡眠一段時間,進行測試
@GetMapping("/testA")
public String testA()
{
try {TimeUnit.MILLISECONDS.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}
return "------testA";
}
開啓兩個窗口,進行來回切換快速刷新來訪問接口testA來測試能不能快速失敗
很不幸,我測試了好幾次,都不能快速失敗,不知道啥情況額·可能是機子性能有點好哈哈~~~有點尷尬
2、關聯模式:
當關聯的資源達到閾值時,就限流自己
當與A關聯的資源B達到閾值後,就限流自己A
B惹事,A掛了,下面進行設置關聯模式
下面通過postman模擬併發密集訪問testB,利用collections來模擬
此時,請求testA接口還能訪問成功,當我們通過postman請求testB接口後,再訪問testA發現已經出現快速失敗了
當postman中的testB接口訪問完成以後,再來看testA接口,發現已經恢復正常了!
測試過程:訪問testB成功-->postman裏新建多線程集合組-->將訪問地址添加進新線程組-->Run-->大批量線程高併發訪問B,導致A失效了
就相當於這種業務場景:下訂單支付,支付系統已經滿載了,此時就會直接讓下訂單服務快速失敗,等支付系統恢復後,下訂單服務恢復正常~
3、鏈路模式:
未完待續~~
三、流控效果:
流量控制官網:https://github.com/alibaba/Sentinel/wiki/%E6%B5%81%E9%87%8F%E6%8E%A7%E5%88%B6
1、直接拒絕 :直接->快速失敗(默認的流控處理)
直接拒絕(RuleConstant.CONTROL_BEHAVIOR_DEFAULT
)方式是默認的流量控制方式,當QPS超過任意規則的閾值後,新的請求就會被立即拒絕,拒絕方式爲拋出FlowException
。這種方式適用於對系統處理能力確切已知的情況下,比如通過壓測確定了系統的準確水位時
直接失敗,拋出異常,Blocked by Sentinel (flow limiting)
源碼位置:com.alibaba.csp.sentinel.slots.block.flow.controller.DefaultController
2、預熱
Warm Up(RuleConstant.CONTROL_BEHAVIOR_WARM_UP
)方式,即預熱/冷啓動方式。當系統長期處於低水位的情況下,當流量突然增加時,直接把系統拉昇到高水位可能瞬間把系統壓垮。通過"冷啓動",讓通過的流量緩慢增加,在一定時間內逐漸增加到閾值上限,給冷系統一個預熱的時間,避免冷系統被壓垮。詳細文檔可以參考 流量控制 - Warm Up 文檔,具體的例子可以參見 WarmUpFlowDemo。
當流量突然增大的時候,我們常常會希望系統從空閒狀態到繁忙狀態的切換的時間長一些。即如果系統在此之前長期處於空閒的狀態,我們希望處理請求的數量是緩步的增多,經過預期的時間以後,到達系統處理請求個數的最大值。Warm Up(冷啓動,預熱)模式就是爲了實現這個目的的。這個場景主要用於啓動需要額外開銷的場景,例如建立數據庫連接等。
公式:閾值除以coldFactor(默認值爲3),經過預熱時長後纔會達到閾值
默認coldFactor爲3,即請求QPS從threshold/3開始,經預熱時長逐漸升至設定的QPS閾值。
限流-冷啓動官網https://github.com/alibaba/Sentinel/wiki/%E9%99%90%E6%B5%81---%E5%86%B7%E5%90%AF%E5%8A%A8
源碼位置:com.alibaba.csp.sentinel.slots.block.flow.controller.WarmUpController
下面進行預熱配置演示testB:
案例:閥值爲10+預熱時長設置5秒。
系統初始化的閥值爲10 / 3約等於3,即閥值剛開始爲3;然後過了5秒後閥值才慢慢升高恢復到10
注意:因爲我機子速度快的原因,5s預熱時長我看不出效果,所以我將預熱時長改爲了10s,所以進行測試會出現正常結果:
當請求一次testB的時候,能正常響應,等進行快速刷新請求testB的時候,會時不時的出現 快速失敗界面,然後等達到預熱時長5s後,再訪問就不會出現快速失敗了,說明已經預熱完成,能處理併發請求了
應用場景:秒殺系統在開啓的瞬間,會有很多流量上來,很有可能把系統打死,預熱方式就是把爲了保護系統,可慢慢的把流量放進來,慢慢的把閥值增長到設置的閥值。
3、勻速排隊
勻速排隊(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER
)方式會嚴格控制請求通過的間隔時間,也即是讓請求以均勻的速度通過,對應的是漏桶算法。詳細文檔可以參考 流量控制 - 勻速器模式,具體的例子可以參見 PaceFlowDemo。
該方式的作用如下圖所示:
這種方式主要用於處理間隔性突發的流量,例如消息隊列。想象一下這樣的場景,在某一秒有大量的請求到來,而接下來的幾秒則處於空閒狀態,我們希望系統能夠在接下來的空閒期間逐漸處理這些請求,而不是在第一秒直接拒絕多餘的請求。
源碼位置:com.alibaba.csp.sentinel.slots.block.flow.controller.RateLimiterController
演示:設置QPS,這裏只能是QPS纔有勻速排隊效果,設置閾值爲1QPS,超時時間爲20s
我們再通過postman模擬請求,通過後臺查看是否有排隊效果
啓動訪問,後臺打印的日誌卻是一秒一次,說明我們的勻速排隊流控設置成功了,不管前臺訪問多麼高,到了我這裏流控就是排隊,1QPS來進行響應,表示設置 勻速排隊成功