Sentinel规则之热点参数限流规则

Sentinel规则之热点参数限流规则


博客导航带你有序的阅读和学习!


文档:

https://github.com/alibaba/Sentinel/wiki/%E7%83%AD%E7%82%B9%E5%8F%82%E6%95%B0%E9%99%90%E6%B5%81

概述

何为热点?热点即经常访问的数据。很多时候我们希望统计某个热点数据中访问频次最高的 Top K 数据,并对其访问进行限制。比如:

  • 商品 ID 为参数,统计一段时间内最常购买的商品 ID 并进行限制
  • 用户 ID 为参数,针对一段时间内频繁访问的用户 ID 进行限制

热点参数限流会统计传入参数中的热点参数,并根据配置的限流阈值与模式,对包含热点参数的资源调用进行限流。热点参数限流可以看做是一种特殊的流量控制,仅对包含热点参数的资源调用生效。

在这里插入图片描述

Sentinel 利用 LRU 策略统计最近最常访问的热点参数,结合令牌桶算法来进行参数级别的流控。

热点参数规则

热点参数规则(ParamFlowRule)类似于流量控制规则(FlowRule):

属性说明默认值
resource资源名,必填
count限流阈值,必填
grade限流模式QPS 模式
durationInSec统计窗口时间长度(单位为秒),1.6.0 版本开始支持1s
controlBehavior流控效果(支持快速失败和匀速排队模式),1.6.0 版本开始支持快速失败
maxQueueingTimeMs最大排队等待时长(仅在匀速排队模式生效),1.6.0 版本开始支持0ms
paramIdx热点参数的索引,必填,对应 SphU.entry(xxx, args) 中的参数索引位置
paramFlowItemList参数例外项,可以针对指定的参数值单独设置限流阈值,不受前面 count 阈值的限制。仅支持基本类型和字符串类型
clusterMode是否是集群参数流控规则false
clusterConfig集群流控相关配置

上面都是摘抄子官方网站,下面使用代码来测试。

我们先看一下热点参数规则的源码:

public class ParamFlowRule extends AbstractRule {
    //限流模式
    private int grade = RuleConstant.FLOW_GRADE_QPS;

    //热点参数的索引
    private Integer paramIdx;

    //The threshold count.
    private double count;

    //流控效果
    private int controlBehavior = RuleConstant.CONTROL_BEHAVIOR_DEFAULT;
    //最大排队等待时长
    private int maxQueueingTimeMs = 0;
    private int burstCount = 0;
    //统计窗口时间长度
    private long durationInSec = 1;

    //参数的额外项,可以针对指定的参数值单独设置限流阈值,不受前面的count影响,仅支持基本数据类型和字符串
    private List<ParamFlowItem> paramFlowItemList = new ArrayList<ParamFlowItem>();

    //额外参数
    private Map<Object, Integer> hotItems = new HashMap<Object, Integer>();

    //是否是集群参数流控规则 默认是false
    private boolean clusterMode = false;
    private ParamFlowClusterConfig clusterConfig;
}

public class ParamFlowItem {
    private String object;//参数值
    private Integer count;//限流阈值
    private String classType;//参数类型
}

实验

初始化规则

public static void initParamFlowRule(){
    List<ParamFlowRule> rules = new ArrayList<>();
    ParamFlowRule rule = new ParamFlowRule();
    //阈值类型:只支持QPS
    rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
    //阈值
    rule.setCount(1);
    //资源名
    rule.setResource("test");
    rule.setParamIdx(0);//指配热点参数的下标
    //统计窗口时间长度
    rule.setDurationInSec(10);

    List<ParamFlowItem> items = new ArrayList<>();
    ParamFlowItem item = new ParamFlowItem();
    item.setClassType(String.class.getTypeName());
    item.setCount(2);
    item.setObject("123456");//需要统计的值

    ParamFlowItem item1 = new ParamFlowItem();
    item1.setClassType(int.class.getName());
    item1.setCount(3);
    item1.setObject("12");

    items.add(item);
    items.add(item1);
    rule.setParamFlowItemList(items);
    rules.add(rule);
    ParamFlowRuleManager.loadRules(rules);
}

上述初始化规则代码相当于按如下在控制台页面配置 :

在这里插入图片描述

逻辑代码

@GetMapping("/test")
public String test(
  				@RequestParam("username") String username, 
  				@RequestParam("password") String password, 
  				@RequestParam("age") int age) {
    String echo = echoService.test(username,password,age);
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
    System.out.println(echo+" | t:"+dateFormat.format(new Date()));
    return "访问成功";
}

public interface EchoService {
    String test(String username, String password, int age);
}

@Service
public class EchoServiceImpl implements EchoService {

    @Override
    @SentinelResource(value = "test",blockHandler = "handleBlockForTest")
    public String test(String username,String password, int age) {
        return "username:"+username +" password:"+password + " age:"+age;
    }

    public String handleBlockForTest(String username, String password,int age, BlockException e){
        return "username:"+username +" password:"+password +" age:"+age+"
          							e:"+e.getClass().getSimpleName();
    }
}

测试1

localhost:8083/test?username=admin&password=123456&age=12
参数索引设置为:0

如果使用上述路径测试,结果为:

可以看出,passed的数量为1条,所以有效的阈值为1,统计的热点参数是username。

在这里插入图片描述

测试2

localhost:8083/test?username=admin&password=123456&age=12
参数索引设置为:1

可以看出,passed的数量为2条,所以有效的阈值为2,统计的热点参数,由于上面设置的为1,所以为password。

在这里插入图片描述

我们将password的123456修改一下,设置为12345,测试结果如下:

passed的条数为1条,所以在额外的参数不匹配时,阈值还原到了第一个热点参数:username。

在这里插入图片描述

总结

热点参数限流规则主要是针对请求参数来统计,并实现限流的。首先热点参数是基于QPS统计,如果参数索引设置为0,则以第一个参数统计为准,阈值也是按照基本参数中的阈值来控制的,但是指定的是额外的参数列表的下标,则需要提供指定的热点参数的值,如果当前访问的参数与预设定的参数不一致,依旧与第一个参数的阈值为准。

在这里插入图片描述

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值