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