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
1
2
如果使用上述路径测试,结果为:

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

测试2
localhost:8083/test?username=admin&password=123456&age=12
参数索引设置为:1
1
2
可以看出,passed的数量为2条,所以有效的阈值为2,统计的热点参数,由于上面设置的为1,所以为password。

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

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

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


————————————————
版权声明:本文为CSDN博主「ooyhao」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/ooyhao/article/details/102746118

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值