微服务系列:Spring Cloud Alibaba 之 Sentinel 热点限流规则

微服务系列:Spring Cloud Alibaba 之 Sentinel 热点限流规则,第1张

微服务系列:Spring Cloud Alibaba 之 Sentinel 热点限流规则

微服务系列:Spring Cloud Alibaba 之 Sentinel 基本流控规则

微服务系列:Spring Cloud Alibaba 之 Sentinel 高级流控规则

微服务系列:Spring Cloud Alibaba 之 Sentinel 熔断降级规则

上面几篇中我们已经学习完了 Sentinel 的基本、高级、熔断规则,这篇我们继续来学习另一个:热点限流

相对来说,这个热点规则比较简单

话不多说,开始今天的学习。

一、概述

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

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

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

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

二、基本使用 1. 引入依赖

要使用热点参数限流功能,需要引入以下依赖:


    com.alibaba.csp
    sentinel-parameter-flow-control
    x.y.z

当然我们如果引了这个,那么久不需要再额外引入上面的这个依赖了:


    com.alibaba.cloud
    spring-cloud-starter-alibaba-sentinel

2. 测试接口
@SentinelResource(value = "testHotspot", blockHandler = "hotSpotBlockHandler")
@GetMapping("/testHotspot")
public String testHotspot(String p1, String p2){
    return "testHotspot....";
}

public String hotSpotBlockHandler(String p1, String p2, BlockException ex){
    return "触发限流!!!";
}

注意:目前 Sentinel 自带的 adapter 仅 Dubbo 方法埋点带了热点参数,其它适配模块(如 Web)默认不支持热点规则,可通过自定义埋点方式指定新的资源名并传入希望的参数。注意自定义埋点的资源名不要和适配模块生成的资源名重复,否则会导致重复统计。

也就是要使用热点限流,必须要自己自定义埋点,这里我们使用了 @SentinelResource 来定义了资源。

3. 控制台定义

在热点规则菜单新增热点规则:

热点规则仅支持 QPS 模式

参数索引从 0 开始,这里的 0 就对应 /testHotspot 接口中的 p1 参数,同理,1 对应 p2 参数

此配置的效果是:**带着参数 p1 访问 /testHotspot 接口,超过阈值则触发限流 **

统计窗口时长:是指触发限流之后在这个时长内接下来的请求都会直接被限流,10秒过去后下次请求重新走规则

4. 启动测试 4.1、情况1

配置好之后,我们启动项目,

只传 p1 参数,浏览器访问:localhost:9201/testHotspot?p1=小黑

快速刷新几次,触发限流

4.2、情况2

我们只传 p2 参数试试,访问:localhost:9201/testHotspot?p2=小胖

发现无论怎么刷新,都不会触发限流,因为我们没有只配置了 参数0

4.3、情况3

我们两个参数都传,访问:localhost:9201/testHotspot?p1=小黑&p2=小胖

发现同样会触发限流。

5. 高级选项

点击 高级选项 会出现热点规则的高级选项

我们来配置一下

点击添加

这个配置的效果是:对于参数 p1 ,参数值是 “小六” 的请求限流阈值调整为 20

就好像 VIP 和普通用户的限流阈值不一样(VIP 要高于普通用户),哈哈哈,笑着笑着就哭了!

启动测试

访问 localhost:9201/testHotspot?p1=小六

凭手速已经达不到这个阈值 20 了。

6. 代码定义

我们可以通过 ParamFlowRuleManager 的 loadRules 方法更新热点参数规则,下面是一个示例:

ParamFlowRule rule = new ParamFlowRule(resourceName)
    .setParamIdx(0)
    .setCount(5);
// 针对 int 类型的参数 PARAM_B,单独设置限流 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));

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

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

对于 @SentinelResource 注解方式定义的资源,若注解作用的方法上有参数,Sentinel 会将它们作为参数传入 SphU.entry(res, args)。比如以下的方法里面 uid 和 type 会分别作为第一个和第二个参数传入 Sentinel API,从而可以用于热点规则判断:

@SentinelResource("myMethod")
public Result doSomething(String uid, int type) {
  // some logic here...
}
三、 其他规则

除了基本流控规则、高级流控规则、熔断降级规则、热点限流规则之外,还有系统规则和授权规则,这两种也不准备再详细讲解了,了解即可,大家可以直接查看官方文档。

系统自适应限流 · alibaba/Sentinel Wiki · GitHub

黑白名单控制 · alibaba/Sentinel Wiki · GitHub

本文结束,祝大家新年快乐!

PS: 都看到这里了,点个赞吧,彦祖!

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5721814.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-18
下一篇 2022-12-18

发表评论

登录后才能评论

评论列表(0条)

保存