javascript
Spring Cloud Alibaba:Sentinel 流控规则
文章目錄
- 1. 前言
- 2. 閾值類型
- 2.1 QPS
- 2.2 線程數
- 3. 流控模式
- 3.1 直接
- 3.2 關聯
- 3.3 鏈路
- 4. 流控效果
- 4.1 快速失敗
- 4.2 Warm Up
- 4.3 排隊等待
1. 前言
在前面的文章中,已經介紹過了 Sentinel安裝和基本使用。這次主要講的是Sentinel 的流量控制規則,使用版本為1.8.0,它提供了以下幾個配置項:
- 資源名: 唯一名稱,默認是接口的請求路徑
- 針對來源: Sentinel可以針對調用者限流,填寫微服務名稱,默認default(不區分來源)
- 閾值類型/單機閾值:
- QPS:當調用該API的QPS達到閾值,進行限流
- 線程數:當調用該API的線程數達到閾值,進行限流
- 是否集群: 不需要
- 流控模式:
- 直接:該API達到限流條件,進行限流
- 關聯:當關聯的資源達到閾值,就限流自己
- 鏈路:只記錄指定鏈路上的流量,指定資源從入口資源進來的流量,如果達到條件,就進行限流(API級別的針對來源)
- 流控效果:
- 快速失敗:直接失敗,拋出異常
- Warm Up:根據codeFactor(冷加載因子,默認3),從 閾值/codeFactor 開始,經過配置的預熱時長,才達到設定的QPS閾值
- 排隊等待:勻速排隊,讓請求以勻速的速度通過,閾值類型必須設置為QPS,否則無效
2. 閾值類型
2.1 QPS
Queries Per Second,每秒請求量。
首先,我們給 /test 接口配置如下流控規則。
| QPS | 10 |
| 流控規則 | 直接 |
| 流控效果 | 快速失敗 |
接著,啟動JMeter在1秒內發送20個請求。結果就是產生大量異常,直接報錯Blocked by Sentinel (flow limiting) ,說明Sentinel攔截生效
2.2 線程數
將上一步的 QPS 改成 線程數,閾值設置為2,測試結果如下:
竟然所有請求都通過了,這是因為CPU的執行速度遠遠超出了我們的想象,并非每個HTTP請求都會New出新的線程進行執行,可能一個線程就全部處理掉了。為了讓CPU創建大量線程,我們改下接口代碼:
重新執行JMeter,結果如下,符合預期:
3. 流控模式
3.1 直接
針對當前資源的接口進行控制,前面的例子用的就是這項配置
3.2 關聯
當關聯的資源達到閾值,就限流自己。例如:當支付接口的調用達到閾值,就限制下單接口。
創建另一個接口 /test2,針對/test資源配置如下限流規則:
接下來,使用JMeter對/test2接口發起大量請求。然后,立刻馬上在瀏覽器訪問/test,就能重現Blocked by Sentinel (flow limiting)的異常。這就是關聯流控的使用方式。
3.3 鏈路
鏈路流控模式指的是,當從某個接口過來的資源達到限流條件時,開啟限流;它的功能有點類似于針對 來源配置項,區別在于:針對來源是針對上級微服務,而鏈路流控是針對上級接口,也就是說它的粒度更細.
舉個例子:
創建一個OrderService,里面寫個getOrder方法,并加上 @SentinelResource 注解,表示當前方法資源名稱是 getOrder
@Service public class OrderServiceImpl implements OrderService {@SentinelResource(value = "getOrder")@Overridepublic String getOrder(String id) {return "Order:" + id;} }在controller分別創建2個接口:order1、order2
@GetMapping("/order1")public String order1(){return orderService.getOrder("111");}@GetMapping("/order2")public String order2(){return orderService.getOrder("222");}打開sentinel控制臺,對getOrder資源進行流控規則設置。
入口資源設置為 /order1,表示從/order1接口調用才進行流控,如果從/order2調用的不做任何控制
在瀏覽器反復調用 http://localhost:8020/order1 ,發現流控沒生效 - -!
這是因為從1.6.3 版本開始, Sentinel Web filter默認收斂所有URL的入口context
1.7.0 版本開始(對應Spring Cloud Alibaba的2.1.1.RELEASE),官方在引入了spring.cloud.sentinel.web-context-unify 參數,用于控制是否收斂context;將其配置為 false 即可根據不同的URL 進行鏈路限流。
官方源碼如下:
如上圖所示:web-context-unify 為true的時候,取到的是收斂的context名稱sentinel_spring_web_context;為false的時候,就可以正確地取到 /order1 資源名。
在 application.yml 修改參數之后,再次測試,就能正常進行限流了
4. 流控效果
4.1 快速失敗
拋出Blocked by Sentinel (flow limiting)異常,前面的例子用的就是這項配置
4.2 Warm Up
預熱、冷啟動
如下圖,系統將從 10/冷卻因子3 開始,經過10秒時間緩慢將閾值升到單機閾值10
配置JMeter,在30秒內發送300次請求,也就是10次/秒。 測試結果如下:
一開始的請求,存在大量報錯,因為這時候閾值從3開始,還沒達到10
到最后,閾值達到10了就不再報錯
4.3 排隊等待
嚴格地控制請求通過的間隔時間,也就是讓請求勻速地通過,對應的是漏桶算法。這種方式適合用于請求以突刺狀來到,這個時候我們不希望一下子把所有的請求都通過,這樣可能會把系統壓垮;同時我們也期待系統以穩定的速度,逐步處理這些請求,以起到“削峰填谷”的效果,而不是拒絕所有請求。
注意:勻速排隊模式暫時不支持 QPS > 1000 的場景。
- 官方手冊:https://github.com/alibaba/Sentinel/wiki/%E6%B5%81%E9%87%8F%E6%8E%A7%E5%88%B6
- 源碼:com.alibaba.csp.sentinel.slots.block.flow.controller.RateLimiterController
測試:設置QPS=1,也就是每秒處理1個請求,剩下的排隊等待,5秒后超時
使用JMeter每秒發送2次請求
從第6秒開始,就開始出現超時異常
總結
以上是生活随笔為你收集整理的Spring Cloud Alibaba:Sentinel 流控规则的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux环境下安装OpenOffice
- 下一篇: Spring Cloud Alibaba