注:Sentinel的監控頁面一開始是沒有東西,需要對監控的服務發起請求后才會出現
流量控制(flow control)
- 原理是監控應用流量的 QPS 或並發線程數等指標,當達到指定的閾值時對流量進行控制,以避免被瞬時的流量高峰沖垮,從而保障應用的高可用性;
兩種規則
- 基於統計並發線程數的流量控制
並發數控制用於保護業務線程池不被慢調用耗盡
Sentinel 並發控制不負責創建和管理線程池,而是簡單統計當前請求上下文的線程數目(正在執行的調用數目);
如果超出閾值,新的請求會被立即拒絕,效果類似於信號量隔離;
- 基於統計QPS的流量控制
當 QPS 超過某個閾值的時候,則采取措施進行流量控制;
控制面板
-
資源名:唯一名稱,默認請求路徑
-
針對來源:
Sentinel
可以針對調用者進行限流,填寫微服務名,指定對哪個微服務進行限流 ,默認default
(不區分來源,全部限制) -
閾值類型/單機閾值:
-
QPS(每秒鍾的請求數量):當調用該接口的QPS達到了閾值的時候,進行限流;
-
線程數:當調用該接口的線程數達到閾值時,進行限流
-
-
是否集群:不需要集群
-
流控模式:
-
直接:接口達到限流條件時,直接限流
-
關聯:當關聯的資源達到閾值時,就限流自己
-
鏈路:只記錄指定鏈路上的流量(指定資源從入口資源進來的流量,如果達到閾值,就可以限流)[api級別的針對來源]
-
-
流控效果
-
快速失敗:直接失敗,就異常
-
Warm Up:根據
codeFactor
(冷加載因子,默認為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#%E6%A6%82%E8%BF%B0]
-
直接快速失敗的效果:
當請求A過來訪問該接口,該請求處理的很慢,還沒有返回數據;此時請求B也過來訪問該接口,這個時候處理請求B需要額外開啟一個線程,請求B則會報錯;
效果如下:
流控模式
- 直接模式
Sentinel的流控模式代表的流控的方式,默認【直接】;
上面的/testA接口的流控,QPS單機閥值為1,代表每秒請求不能超出1,要不然就做流控處理,處理方式直接調用失敗;
調用/testA,慢一點請求,正常返回;快速請求幾次,超過閥值;接口返回了Blocked by Sentinel (flow limiting),代表被限流了;
- 關聯模式
設置效果:當關聯資源/testB的QPS閾值超過1時,就限流/testA的Rest的訪問地址,當關聯資源到資源閾值后限制配置好的資源名;
關聯通俗點說就是,當關聯的資源達到閥值,就限流自己;
應用場景: 比如支付接口達到閾值,就要限流下訂單的接口,防止一直有訂單
鏈路流控模式指的是,當從某個接口過來的資源達到限流條件時,開啟限流;它的功能有點類似於針對 來源配置項,區別在於:針對來源是針對上級微服務,而鏈路流控是針對上級接口,也就是說它的粒度 更細;
1.編寫一個service
@Service public class OrderServiceImpl implements OrderService { @Override @SentinelResource(value = "getOrder", blockHandler = "handleException") public CommonResult getOrder() { return new CommonResult(0, String.valueOf(new Random().nextInt())); } public CommonResult handleException(BlockException ex) { return new CommonResult(-1, ex.getClass().getCanonicalName() + "\t服務不可用"); } }
2.在Controller聲明兩個方法
@Autowired private OrderService orderService; @GetMapping("/test1") public CommonResult test1() { return orderService.getOrder(); } @GetMapping("/test2") public CommonResult test2() { return orderService.getOrder(); }
注意:
從1.6.3 版本開始, Sentinel Web filter默認收斂所有URL的入口context,因此鏈路限流不生效;
1.7.0 版本開始(對應Spring Cloud Alibaba的2.1.1.RELEASE),官方在CommonFilter
引入了WEB_CONTEXT_UNIFY
參數,用於控制是否收斂context;將其配置為 false 即可根據不同的URL 進行鏈路限流; [https://github.com/alibaba/Sentinel/issues/1213]
@Configuration public class FilterContextConfig { @Bean public FilterRegistrationBean sentinelFilterRegistration() { FilterRegistrationBean registration = new FilterRegistrationBean(); registration.setFilter(new CommonFilter()); registration.addUrlPatterns("/*"); // 入口資源關閉聚合 registration.addInitParameter(CommonFilter.WEB_CONTEXT_UNIFY, "false"); registration.setName("sentinelFilter"); registration.setOrder(1); return registration; } }
流量效果
-
快速失敗
直接拒絕(
RuleConstant.CONTROL_BEHAVIOR_DEFAULT
)方式是默認的流量控制方式,當QPS超過任意規則的閾值后,新的請求就會被立即拒絕,拒絕方式為拋出FlowException
。這種方式適用於對系統處理能力確切已知的情況下,比如通過壓測確定了系統的准確水位時。具體的例子參見[
Warm Up(RuleConstant.CONTROL_BEHAVIOR_WARM_UP
)方式,即預熱/冷啟動方式。當系統長期處於低水位的情況下,當流量突然增加時,直接把系統拉升到高水位可能瞬間把系統壓垮。通過"冷啟動",讓通過的流量緩慢增加,在一定時間內逐漸增加到閾值上限,給冷系統一個預熱的時間,避免冷系統被壓垮。詳細文檔可以參考
[
根據codeFactor
(冷加載因子,默認為3)的值,即請求 QPS 從 threshold / 3
系統初始化的默認閾值為10 / 3,即為3,也就是剛開始的時候閾值只有3,當經過5s后,閾值才慢慢提高到10;
源碼:com.alibaba.csp.sentinel.slots.block.flow.controller.WarmUpController
應用場景:秒殺系統的開啟瞬間,會有很多流量上來,很可能會把系統打掛,預熱方式就是為了保護系統,可以慢慢的把流量放進來,慢慢的把閾值增長到設定值;
勻速排隊,讓請求以均勻的速度通過,閾值類型必須設置成QPS
這種方式主要用於處理間隔性突發的流量,例如消息隊列。想象一下這樣的場景,在某一秒有大量的請求到來,而接下來的幾秒則處於空閑狀態,我們希望系統能夠在接下來的空閑期間逐漸處理這些請求,而不是在第一秒直接拒絕多余的請求。
源碼:com.alibaba.csp.sentinel.slots.block.flow.controller.RateLimiterController
[