聊聊Sentinel流量控制
今日目標(biāo)
- 安裝Sentinel
- 項(xiàng)目整合Sentinel
1.流量控制
雪崩問題雖然有四種方案(流量控制、熔斷降級(jí)、線程隔離、超時(shí)處理),流量控制是避免服務(wù)因突發(fā)的流量而發(fā)生故障,是對(duì)微服務(wù)雪崩問題的預(yù)防,所以我們先學(xué)習(xí)Sentinel的流量控制或者說是限流。
Sentinel如何做到流量控制?
Sentinel監(jiān)控SpringMVC的每一個(gè)端點(diǎn)(Endpoint),因此SpringMVC的每一個(gè)端點(diǎn)(Endpoint)就是調(diào)用鏈路中的一個(gè)資源。請(qǐng)求進(jìn)入微服務(wù)時(shí),訪問DispatcherServlet,然后進(jìn)入Controller、Service、Mapper,這樣的一個(gè)調(diào)用鏈就叫做簇點(diǎn)鏈路。簇點(diǎn)鏈路中被監(jiān)控的每一個(gè)接口就是一個(gè)資源。
例如,我們剛才訪問的order-service中的OrderController中的端點(diǎn):/order/{Id}
圖片
后續(xù)我們的流控、熔斷都將針對(duì)簇點(diǎn)鏈路中的資源進(jìn)行發(fā)起,因此我們可以點(diǎn)擊對(duì)應(yīng)資源后面的按鈕來設(shè)置規(guī)則:
- 流控:流量控制
- 降級(jí):降級(jí)熔斷
- 熱點(diǎn):熱點(diǎn)參數(shù)限流,是限流的一種
- 授權(quán):請(qǐng)求的權(quán)限控制
2.快速上手
點(diǎn)擊編輯資源 /order/{id} 的流控按鈕
圖片
表單中可以填寫限流規(guī)則,如下:
圖片
填寫單機(jī)閾值:2,其含義是:限制資源/order/{id} 的QPS為2,表示每秒只允許2次請(qǐng)求,超過的請(qǐng)求會(huì)被攔截并報(bào)錯(cuò)。
2.1.測(cè)試
快速刷新瀏覽器時(shí),會(huì)發(fā)現(xiàn)出現(xiàn)下述錯(cuò)誤信息
圖片
但一般來說生產(chǎn)的流量要更多,此處我們將借助于一個(gè)壓測(cè)工具:Jmeter做更為全面的壓力測(cè)試
2.2. 利用Jmeter測(cè)試
下載
可以Apache Jmeter官網(wǎng)下載,地址:https://jmeter.apache.org/
圖片
解壓
Jmeter下載下來之后,解壓縮即可使用,目錄結(jié)構(gòu)如下:
圖片
其中的bin目錄就是執(zhí)行的腳本,其中包含啟動(dòng)腳本:
圖片
運(yùn)行
雙擊jmeter.bat即可運(yùn)行:
圖片
Jmeter測(cè)試
使用Jmeter測(cè)試QPS < 2
圖片
此規(guī)則如下:10個(gè)請(qǐng)求在1s內(nèi)執(zhí)行完成,此時(shí)生效的限流規(guī)則上面我們配置的為2(每秒最多2個(gè)請(qǐng)求通過)
圖片
啟動(dòng)
圖片
運(yùn)行啟動(dòng)后會(huì)發(fā)現(xiàn)每秒能通過的請(qǐng)求最多2個(gè)(如下展示可能會(huì)亂序,以請(qǐng)求時(shí)間為準(zhǔn)):
圖片
此時(shí),我們就完成了流量控制的入門效果,這一效果也是流控模式之一的直接模式。
如果您覺得本文不錯(cuò),歡迎關(guān)注,點(diǎn)贊,收藏支持,您的關(guān)注是我堅(jiān)持的動(dòng)力!
3. Sentinel流控模式
Sentinel添加限流規(guī)則時(shí),點(diǎn)擊高級(jí)選項(xiàng),可以選擇三種流控模式:
- 直接:統(tǒng)計(jì)當(dāng)前資源的請(qǐng)求,觸發(fā)閾值時(shí)對(duì)當(dāng)前資源直接限流,也是默認(rèn)的模式
- 關(guān)聯(lián):統(tǒng)計(jì)與當(dāng)前資源相關(guān)的另一個(gè)資源,觸發(fā)閾值時(shí),對(duì)當(dāng)前資源限流
- 鏈路:統(tǒng)計(jì)從指定鏈路訪問到本資源的請(qǐng)求,觸發(fā)閾值時(shí),對(duì)指定鏈路限流
圖片
快速入門就是直接模式,也是默認(rèn)方式
3.1 Sentinel流控-直接模式
什么是Sentinel流控直接模式
直接模式:針對(duì)當(dāng)前資源的請(qǐng)求,觸發(fā)閾值時(shí)就對(duì)當(dāng)前資源直接限流,也是默認(rèn)的模式。
直接模式適用場(chǎng)景
對(duì)于沒有明顯差異、特殊化場(chǎng)景的都可以采用直接模式,它更簡(jiǎn)單易用
3.2 Sentinel流控-關(guān)聯(lián)模式
什么是關(guān)聯(lián)模式
關(guān)聯(lián)模式:統(tǒng)計(jì)與當(dāng)前資源相關(guān)的另一個(gè)資源,觸發(fā)閾值時(shí),對(duì)當(dāng)前資源限流
關(guān)聯(lián)模式適用場(chǎng)景
在一個(gè)商城系統(tǒng)中,用戶支付時(shí)需要修改訂單狀態(tài),同時(shí)用戶需要查詢訂單。查詢和修改操作會(huì)爭(zhēng)搶數(shù)據(jù)庫鎖(讀速過高影響寫、寫速過高影響讀速度),爭(zhēng)搶本身帶來的開銷會(huì)降低整體吞吐量。此時(shí)我們需要優(yōu)先保證修改訂單的功能,對(duì)查詢對(duì)單業(yè)務(wù)限流。即當(dāng)A觸發(fā)條件時(shí),被關(guān)聯(lián)的資源B產(chǎn)生限流。
圖片
關(guān)聯(lián)模式實(shí)現(xiàn)關(guān)聯(lián)規(guī)則建立如下:
圖片
規(guī)則解釋
當(dāng)訪問/write接口次數(shù)超過閾值(我們對(duì)/write寫有自己的流控規(guī)則),就會(huì)對(duì)/read接口進(jìn)行限流,從而避免對(duì):/write資源的影響
關(guān)聯(lián)規(guī)則實(shí)戰(zhàn)
需求
- 在OrderController中新建兩個(gè)端點(diǎn)(http接口):/order/query 和 /order/update
- 配置關(guān)聯(lián)流控規(guī)則:當(dāng)/update接口訪問超過QPS>3時(shí),對(duì)/query進(jìn)行限流
【步驟一】:定義/order/query接口
@GetMapping("/query")
public String queryOrder() {
return "查詢order成功";
}
【步驟二】:定義/order/update接口
@GetMapping("/update")
public String updateOrder() {
return "更新order成功";
}
【步驟三】 重啟服務(wù),查看sentinel控制臺(tái)的簇點(diǎn)鏈路
重啟SentinelOrderApplication服務(wù)后,瀏覽器訪問端點(diǎn):http://localhost:9092/order/query、http://localhost:9092/order/update,訪問Sentinel控制臺(tái),查看到新的端點(diǎn)信息:
圖片
【步驟四】 配置關(guān)聯(lián)流控規(guī)則
例子是對(duì)/order/query接口進(jìn)行限流,那么就點(diǎn)擊其后面對(duì)應(yīng)按鈕。
圖片
配置流控規(guī)則如下:
注意:我們是針對(duì)誰做限流,就點(diǎn)擊對(duì)應(yīng)資源的流控按鈕,此處我們針對(duì):/order/query
圖片
【步驟五】 Jemter測(cè)試配置關(guān)聯(lián)流控
Jmeter壓測(cè)驗(yàn)證,持續(xù)時(shí)長(zhǎng)10s,qps=10,目的是持續(xù)造成超過配置閾值的窗口期,給用戶訪問驗(yàn)證的時(shí)間
可以看到100個(gè)用戶,10秒,因此QPS為10,超過了我們?cè)O(shè)定的閾值:3
查看HTTP請(qǐng)求
圖片
請(qǐng)求的目標(biāo)是/order/update,這樣端點(diǎn)/order/update就會(huì)觸發(fā)閾值。
注意:限流的目標(biāo)是/order/query,我們?cè)跒g覽器訪問,可以發(fā)現(xiàn):
圖片
3.3. Sentinel流控-鏈路模式
什么是鏈路模式
鏈路模式:針對(duì)從指定鏈路訪問到本資源的請(qǐng)求做統(tǒng)計(jì),判斷是否超過閾值
鏈路模式適用場(chǎng)景
作為業(yè)務(wù)開發(fā)人員,我們有一個(gè)訂單查詢業(yè)務(wù),同時(shí)輸出做頁面展現(xiàn),訪問鏈路:自身系統(tǒng)Controller-->查詢訂單接口。此時(shí)數(shù)據(jù)團(tuán)隊(duì)需要依賴我們的接口做駕駛艙信息,因?yàn)槲覀儗⒉樵冇唵谓涌诒┞督o別的團(tuán)隊(duì),即新增一條訪問鏈路:數(shù)據(jù)團(tuán)隊(duì)Controller-->查詢訂單接口。自身系統(tǒng)的QPS我們根據(jù)壓測(cè)做過合理評(píng)估,但是數(shù)據(jù)團(tuán)隊(duì)的請(qǐng)求我們并未考慮,假設(shè)有上萬的請(qǐng)求過來,我們自身的系統(tǒng)性能也將收到明顯影響。此時(shí)我們就需要將來自數(shù)據(jù)團(tuán)隊(duì)的調(diào)用加上限流。如下
圖片
鏈路模式實(shí)現(xiàn)例如有兩條請(qǐng)求鏈路:
- /user --> /userinfo
- /login --> /userinfo
如果只希望統(tǒng)計(jì)從/login進(jìn)入到/userinfo請(qǐng)求,則可以這樣配置:
圖片
鏈路規(guī)則實(shí)戰(zhàn)
需求
有查詢訂單(/query)和創(chuàng)建訂單(/createOrder)業(yè)務(wù),兩者都需要查詢商品(service層方法queryGoods)。針對(duì)從查詢訂單進(jìn)入到查詢商品的請(qǐng)求統(tǒng)計(jì),并設(shè)置限流。
【步驟一】:定義/order/query接口
@GetMapping("/query")
public String queryOrder() {
orderService.queryGoods();;
return "查詢order成功";
}
【步驟二】:定義/order/create接口
@GetMapping("/create")
public String createOrder() {
// 查詢商品
orderService.queryGoods();
// 查詢訂單
System.out.println("新增訂單");
return "新增order成功";
}
【步驟三】:order-service服務(wù)中,給OrderService接口添加一個(gè)queryGoods方法:
public interface OrderService {
/**
* 創(chuàng)建訂單
*/
Long create(Order order);
void queryGoods();
}
【步驟四】:order-service服務(wù)中,給OrderService接口實(shí)現(xiàn)了OrderServiceImpl添加一個(gè)queryGoods方法:
@Override
@SentinelResource("goods")
public void queryGoods(){
System.out.println("查詢商品");
}
注意:
默認(rèn)情況下,OrderService中的方法是不被Sentinel監(jiān)控的,需要我們自己通過注解來標(biāo)記要監(jiān)控的方法。
給OrderServiceImpl的queryGoods方法添加@SentinelResource注解
【步驟五】:修改application.ym
鏈路模式中,是對(duì)不同來源的兩個(gè)鏈路做監(jiān)控。但是sentinel默認(rèn)會(huì)給進(jìn)入SpringMVC的所有請(qǐng)求設(shè)置同一個(gè)root資源,會(huì)導(dǎo)致鏈路模式失效。
我們需要關(guān)閉這種對(duì)SpringMVC的資源聚合,修改order-service服務(wù)的application.yml文件
spring:
cloud:
sentinel:
web-context-unify: false # 關(guān)閉context整合
【步驟六】:給queryGoods設(shè)置限流規(guī)則,從/order/query進(jìn)入queryGoods的方法限制QPS必須小于2
注意:設(shè)置規(guī)則之前同樣需要訪問才會(huì)產(chǎn)生簇點(diǎn)鏈路,才可以針對(duì)性設(shè)置規(guī)則,因此需要重啟服務(wù)+訪問新接口
圖片
圖片
只統(tǒng)計(jì)從/order/query進(jìn)入/goods的資源,QPS閾值為2,超出則被限流。
【步驟七】 Jemter測(cè)試配置鏈路流控
啟動(dòng)Jmeter壓測(cè),預(yù)期/order/create不受影響,而/order/query最多允許放行流量=2
/order/create
圖片
圖片
/order/query
圖片
圖片
總結(jié)
流控模式有哪些?
- 直接:對(duì)當(dāng)前資源限流
- 關(guān)聯(lián):高優(yōu)先級(jí)資源觸發(fā)閾值,對(duì)低優(yōu)先級(jí)資源限流。
- 鏈路:閾值統(tǒng)計(jì)時(shí),只統(tǒng)計(jì)從指定資源進(jìn)入當(dāng)前資源的請(qǐng)求,是對(duì)請(qǐng)求來源的限流