上一篇是寫如何動态限流的,粒度是對所有的通路者,突然今天有個需求,是這樣,需要根據不同的租戶來限流,怎麼做呢?來看下吧。
追蹤源碼
-
這個類中,就是昨天我們nacos的那些配置,代碼片段如下:com.alibaba.csp.sentinel.adapter.gateway.common.rule#GatewayFlowRule
public class GatewayFlowRule {
private String resource;
private int resourceMode = SentinelGatewayConstants.RESOURCE_MODE_ROUTE_ID;
private int grade = RuleConstant.FLOW_GRADE_QPS;
private double count;
private long intervalSec = 1;
private int controlBehavior = RuleConstant.CONTROL_BEHAVIOR_DEFAULT;
private int burst;
/**
* For throttle (rate limiting with queueing).
*/
private int maxQueueingTimeoutMs = 500;
/**
* For parameter flow control. If not set, the gateway rule will be
* converted to normal flow rule.
*/
private GatewayParamFlowItem paramItem;
}
- 注意這個GatewayParamFlowItem,這代碼也貼出來:
public class GatewayParamFlowItem {
/**
* Should be set when applying to parameter flow rules.
*/
private Integer index;
/**
* Strategy for parsing item (e.g. client IP, arbitrary headers and URL parameters).
*/
private int parseStrategy;
/**
* Field to get (only required for arbitrary headers or URL parameters mode).
*/
private String fieldName;
/**
* Matching pattern. If not set, all values will be kept in LRU map.
*/
private String pattern;
/**
* Matching strategy for item value.
*/
private int matchStrategy = SentinelGatewayConstants.PARAM_MATCH_STRATEGY_EXACT;
}
分析參數作用
其中網關限流規則 GatewayFlowRule 的字段解釋如下:
- resource:資源名稱,可以是網關中的 route 名稱或者使用者自定義的 API 分組名稱。
- resourceMode:規則是針對 API Gateway 的 route(RESOURCE_MODE_ROUTE_ID)還是使用者在 Sentinel 中定義的 API 分組(RESOURCE_MODE_CUSTOM_API_NAME),預設是 route。
- grade:限流名額次元,同限流規則的 grade 字段。
- count:限流門檻值
- intervalSec:統計時間視窗,機關是秒,預設是 1 秒。
- controlBehavior:流量整形的控制效果,同限流規則的 controlBehavior 字段,目前支援快速失敗和勻速排隊兩種模式,預設是快速失敗。
- burst:應對突發請求時額外允許的請求數目。
- maxQueueingTimeoutMs:勻速排隊模式下的最長排隊時間,機關是毫秒,僅在勻速排隊模式下生效。
- paramItem:參數限流配置。若不提供,則代表不針對參數進行限流,該網關規則将會被轉換成普通流控規則;否則會轉換成熱點規則。其中的字段:
- parseStrategy:從請求中提取參數的政策,目前支援提取來源 * * IP(PARAM_PARSE_STRATEGY_CLIENT_IP)、Host(PARAM_PARSE_STRATEGY_HOST)、任意 Header(PARAM_PARSE_STRATEGY_HEADER)和任意 URL 參數(PARAM_PARSE_STRATEGY_URL_PARAM)四種模式。
- fieldName:若提取政策選擇 Header 模式或 URL 參數模式,則需要指定對應的 header 名稱或 URL 參數名稱。
- pattern:參數值的比對模式,隻有比對該模式的請求屬性值會納入統計和流控;若為空則統計該請求屬性的所有值。(1.6.2 版本開始支援)
- matchStrategy:參數值的比對政策,目前支援精确比對(PARAM_MATCH_STRATEGY_EXACT)、子串比對(PARAM_MATCH_STRATEGY_CONTAINS)和正則比對(PARAM_MATCH_STRATEGY_REGEX)。(1.6.2 版本開始支援)
分析HEADER這種模式
- 通過調試發現,以下規則就是我所需要的那種,通過對head裡面的
字段埋點,如果patter完全比對t1,那麼就走限流。X-Sentinel-Flag
Set<GatewayFlowRule> rules = new HashSet<>();
rules.add(new GatewayFlowRule("httpbin_route")
.setCount(1)
.setIntervalSec(1)
.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER)
.setMaxQueueingTimeoutMs(600)
.setParamItem(new GatewayParamFlowItem()
.setParseStrategy(SentinelGatewayConstants.PARAM_PARSE_STRATEGY_HEADER)
.setFieldName("X-Sentinel-Flag")
.setPattern("t1")
.setMatchStrategy(PARAM_MATCH_STRATEGY_EXACT)
)
);
試下sentinel能否配置
[
{
"resource": "consumer_server",
"count": 2,
"controlBehavior":2,
"paramItem": {
"parseStrategy": 2,
"fieldName": "X-Sentinel-Flag",
"pattern": "t1",
"matchStrategy":0
}
}
]
測試
- 頻繁通路
,并且head添加http://localhost:28080/service-consumer-fallback-sentinel/helloByFeign
這個字段,值為t1會發現X-Sentinel-Flag
curl 'http://localhost:28080/service-consumer-fallback-sentinel/helloByFeign' -H 'Connection: keep-alive' -H 'Cache-Control: max-age=0' -H 'Upgrade-Insecure-Requests: 1' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36' -H 'Sec-Fetch-User: ?1' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3' -H 'Sec-Fetch-Site: none' -H 'Sec-Fetch-Mode: navigate' -H 'Accept-Encoding: gzip, deflate, br' -H 'Accept-Language: zh-CN,zh;q=0.9' -H 'Cookie: JSESSIONID=585DA8EC06EA00FBD46FF54BE6833677' -H 'x-sentinel-flag: t1' --compressed
- 如果沒有header或者header不是t1就不會有限制
參考
- https://mp.weixin.qq.com/s/5uGnFSPql_crxivDs-G1dQ