Sentinel(九)之热点参数限流
轉(zhuǎn)載自??熱點(diǎn)參數(shù)限流
Overview
何為熱點(diǎn)?熱點(diǎn)即經(jīng)常訪問的數(shù)據(jù)。很多時(shí)候我們希望統(tǒng)計(jì)某個(gè)熱點(diǎn)數(shù)據(jù)中訪問頻次最高的 Top K 數(shù)據(jù),并對(duì)其訪問進(jìn)行限制。比如:
- 商品 ID 為參數(shù),統(tǒng)計(jì)一段時(shí)間內(nèi)最常購(gòu)買的商品 ID 并進(jìn)行限制
- 用戶 ID 為參數(shù),針對(duì)一段時(shí)間內(nèi)頻繁訪問的用戶 ID 進(jìn)行限制
熱點(diǎn)參數(shù)限流會(huì)統(tǒng)計(jì)傳入?yún)?shù)中的熱點(diǎn)參數(shù),并根據(jù)配置的限流閾值與模式,對(duì)包含熱點(diǎn)參數(shù)的資源調(diào)用進(jìn)行限流。熱點(diǎn)參數(shù)限流可以看做是一種特殊的流量控制,僅對(duì)包含熱點(diǎn)參數(shù)的資源調(diào)用生效。
Sentinel 利用 LRU 策略統(tǒng)計(jì)最近最常訪問的熱點(diǎn)參數(shù),結(jié)合令牌桶算法來進(jìn)行參數(shù)級(jí)別的流控。熱點(diǎn)參數(shù)限流支持集群模式。
基本使用
要使用熱點(diǎn)參數(shù)限流功能,需要引入以下依賴:
<dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-parameter-flow-control</artifactId><version>x.y.z</version> </dependency>然后為對(duì)應(yīng)的資源配置熱點(diǎn)參數(shù)限流規(guī)則,并在?entry?的時(shí)候傳入相應(yīng)的參數(shù),即可使熱點(diǎn)參數(shù)限流生效。
注:若自行擴(kuò)展并注冊(cè)了自己實(shí)現(xiàn)的?SlotChainBuilder,并希望使用熱點(diǎn)參數(shù)限流功能,則可以在 chain 里面合適的地方插入?ParamFlowSlot。
那么如何傳入對(duì)應(yīng)的參數(shù)以便 Sentinel 統(tǒng)計(jì)呢?我們可以通過?SphU?類里面幾個(gè)?entry?重載方法來傳入:
public static Entry entry(String name, EntryType type, int count, Object... args) throws BlockExceptionpublic static Entry entry(Method method, EntryType type, int count, Object... args) throws BlockException其中最后的一串?args?就是要傳入的參數(shù),有多個(gè)就按照次序依次傳入。比如要傳入兩個(gè)參數(shù)?paramA?和?paramB,則可以:
// paramA in index 0, paramB in index 1. // 若需要配置例外項(xiàng)或者使用集群維度流控,則傳入的參數(shù)只支持基本類型。 SphU.entry(resourceName, EntryType.IN, 1, paramA, paramB);注意:若 entry 的時(shí)候傳入了熱點(diǎn)參數(shù),那么 exit 的時(shí)候也一定要帶上對(duì)應(yīng)的參數(shù)(exit(count, args)),否則可能會(huì)有統(tǒng)計(jì)錯(cuò)誤。正確的示例:
Entry entry = null; try {entry = SphU.entry(resourceName, EntryType.IN, 1, paramA, paramB);// Your logic here. } catch (BlockException ex) {// Handle request rejection. } finally {if (entry != null) {entry.exit(1, paramA, paramB);} }對(duì)于?@SentinelResource?注解方式定義的資源,若注解作用的方法上有參數(shù),Sentinel 會(huì)將它們作為參數(shù)傳入?SphU.entry(res, args)。比如以下的方法里面?uid?和?type?會(huì)分別作為第一個(gè)和第二個(gè)參數(shù)傳入 Sentinel API,從而可以用于熱點(diǎn)規(guī)則判斷:
@SentinelResource("myMethod") public Result doSomething(String uid, int type) {// some logic here... }熱點(diǎn)參數(shù)規(guī)則
熱點(diǎn)參數(shù)規(guī)則(ParamFlowRule)類似于流量控制規(guī)則(FlowRule):
| resource | 資源名,必填 | ? |
| count | 限流閾值,必填 | ? |
| grade | 限流模式 | QPS 模式 |
| durationInSec | 統(tǒng)計(jì)窗口時(shí)間長(zhǎng)度(單位為秒),1.6.0 版本開始支持 | 1s |
| controlBehavior | 流控效果(支持快速失敗和勻速排隊(duì)模式),1.6.0 版本開始支持 | 快速失敗 |
| maxQueueingTimeMs | 最大排隊(duì)等待時(shí)長(zhǎng)(僅在勻速排隊(duì)模式生效),1.6.0 版本開始支持 | 0ms |
| paramIdx | 熱點(diǎn)參數(shù)的索引,必填,對(duì)應(yīng)?SphU.entry(xxx, args)?中的參數(shù)索引位置 | ? |
| paramFlowItemList | 參數(shù)例外項(xiàng),可以針對(duì)指定的參數(shù)值單獨(dú)設(shè)置限流閾值,不受前面?count?閾值的限制。僅支持基本類型和字符串類型 | ? |
| clusterMode | 是否是集群參數(shù)流控規(guī)則 | false |
| clusterConfig | 集群流控相關(guān)配置 | ? |
我們可以通過?ParamFlowRuleManager?的?loadRules?方法更新熱點(diǎn)參數(shù)規(guī)則,下面是一個(gè)示例:
ParamFlowRule rule = new ParamFlowRule(resourceName).setParamIdx(0).setCount(5); // 針對(duì) int 類型的參數(shù) PARAM_B,單獨(dú)設(shè)置限流 QPS 閾值為 10,而不是全局的閾值 5. ParamFlowItem item = new ParamFlowItem().setObject(String.valueOf(PARAM_B)).setClassType(int.class.getName()).setCount(10); rule.setParamFlowItemList(Collections.singletonList(item));ParamFlowRuleManager.loadRules(Collections.singletonList(rule));示例
示例可參見?sentinel-demo-parameter-flow-control。
總結(jié)
以上是生活随笔為你收集整理的Sentinel(九)之热点参数限流的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 为什么你们不在乎QQ等级为什么你们不在乎
- 下一篇: 各家的自拍旗舰各家的自拍旗舰店