上一篇是写如何动态限流的,粒度是对所有的访问者,突然今天有个需求,是这样,需要根据不同的租户来限流,怎么做呢?来看下吧。
在这里插入图片描述

追踪源码

  • com.alibaba.csp.sentinel.adapter.gateway.common.rule#GatewayFlowRule 这个类中,就是昨天我们nacos的那些配置,代码片段如下:
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里面的X-Sentinel-Flag字段埋点,如果patter完全匹配t1,那么就走限流。
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
    }
  }
]

测试

  • 频繁访问http://localhost:28080/service-consumer-fallback-sentinel/helloByFeign,并且head添加X-Sentinel-Flag这个字段,值为t1会发现
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
Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐