李林超博客
首页
归档
留言
友链
动态
关于
归档
留言
友链
动态
关于
首页
Java
正文
05.Sentinel热点key限流和系统规则
Leefs
2023-01-17 PM
1300℃
0条
[TOC] ### 一、概述 *官网地址:[热点参数限流](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 | 集群流控相关配置 | | **兜底方法** 兜底方法分为两种:**系统默认**和**客户自定义** 根据之前的案例,都是使用sentinel系统默认的提示:Blocked by Sentinel (flow limiting)。 **那我们能不能自定义兜底方法呢?类似hystrix,某个方法出问题了,就找对应的兜底降级方法?** 类似于**@HystrixCommand,** 引入**@SentinelResource**注解。 ### 三、测试案例 #### 3.1 业务类方法 在服务`sentinel-service-demo01`的业务类中增加如下热点测试方法 ```java @GetMapping("/testHotKey") @SentinelResource(value = "testHotKey", blockHandler = "del_testHotKey") //这里的名称可以随便写,但是一般跟rest地址一样 public String testHotkey(@RequestParam(value = "p1", required = false) String p1, @RequestParam(value = "p1", required = false) String p2) { return "------testHotkey"; } //这里是我们自定义的兜底方法,BlockException不要打成了BlockedException public String del_testHotKey(String p1, String p2, BlockException e) { return "这次不用默认的兜底提示Blocked by Sentinel(flow limiting),自定义提示:del_testHotKeyo(╥﹏╥)o..."; } ``` > 注解`@SentinelResource(value = "testHotKey", blockHandler = "del_testHotKey")` 说明 + `value = "testHotKey"`:是一个标识(Sentinel资源名),与rest的`/testHotKey`对应,这里value的值可以任意写,但是一般约定与rest地址一致,唯一区别是没有`/`。 + `blockHandler = "del_testHotKey"`:则表示如果违背了Sentinel中配置的流控规则,就会调用我们自己的兜底方法`del_testHotKey` #### 3.2 配置热点key限流规则 > 绑定testHotKey资源,把testHotKey对应的第一个参数作为热点key进行监控。 > > **设定热点限流规则**:当该资源的访问QPS超过1次/s的时候,产生限流并执行自定义的del_testHotKey兜底方法 > > **简而言之**:方法testHotKey里面第一个参数只要QPS超过每秒1次,马上降级处理。 需要访问一次`http://localhost:8401/testHotKey?p1=1`的控制器接口,然后才会在Sentinel中显示出簇点链路。 根据上面的控制器指定的请求参数,索引为0的参数是p1,所以只要请求的路径中有p1这个请求参数都会被设置的规则进行限流,限流的就会执行兜底放法。  #### 3.3 测试 **(1)访问如下地址** ``` http://localhost:8401/testHotKey?p1=a&p2=b ``` 如果每秒一次进行访问,则可以正常显示,如果访问次数每秒超过一次,则会触发热点限流,执行自定义兜底方法。  **(2)如果去掉参数p1,仅传入参数p2**  不管我们点击多快都没有影响,并没有触发热点限流。 **(3)现在开两个访问** + 通过jmeter压测 ``` http://localhost:8401/testHotKey?p1=a&p2=b ```  + 再单独使用浏览器访问`http://localhost:8401/testHotKey?p2=b`  发现只带参数p2访问没有任何影响。 **(4)不配置blockeHandler(兜底方法)** ```java @GetMapping("/testHotKey") @SentinelResource(value = "testHotKey") //这里的名称可以随便写,但是一般跟rest地址一样 public String testHotkey(@RequestParam(value = "p1", required = false) String p1, @RequestParam(value = "p1", required = false) String p2) { return "------testHotkey"; } ``` 触发热点限流降级会出现error page,对用户不友好。 #### 3.4 参数例外项 上述案例演示了第一个参数p1,当QPS超过1秒1次点击后马上被限流 > 参数例外项:指定参数的具体值是什么,以及对该参数的阈值是多少,例如索引为0的参数`p1=5`那么久符合了参数值是5,那他的限流阈值就可以达到一秒钟QPS 200个的请求,如果参数不是5,那么p1的请求限制QPS就是一秒钟一个 > > 字面理解:我对该项配置的理解就是,针对传入参数的特定值进行单独设置阈值。以达到对传入的参数值进行精准控制。 **需求** > 当p1=5时,QPS达到200才限流降级  最后点击绿色【添加】按钮。 **测试** 通过浏览器访问如下地址,即使点击在快也没有限流。 ``` http://localhost:8401/testHotKey?p1=5&p2=b ```  > 注意:@SentinelResource只对触发Sentinel配置项产生的异常进行兜底,不管Java运行异常 ### 四、系统规则(系统自适应限流) #### 4.1 概述 系统保护规则是从应用级别的入口流量进行控制,从单台机器的 load、CPU 使用率、平均 RT、入口 QPS 和并发线程数等几个维度监控应用指标,让系统尽可能跑在最大吞吐量的同时保证系统整体的稳定性。 系统保护规则是应用整体维度的,而不是资源维度的,并且**仅对入口流量生效**。入口流量指的是进入应用的流量(`EntryType.IN`),比如 Web 服务或 Dubbo 服务端接收的请求,都属于入口流量。 #### 4.2 系统规则 **系统规则支持以下的模式**: - **Load 自适应**(仅对 Linux/Unix-like 机器生效):系统的 load1 作为启发指标,进行自适应系统保护。当系统 load1 超过设定的启发值,且系统当前的并发线程数超过估算的系统容量时才会触发系统保护(BBR 阶段)。系统容量由系统的 `maxQps * minRt` 估算得出。设定参考值一般是 `CPU cores * 2.5`。 - **CPU usage**(1.5.0+ 版本):当系统 CPU 使用率超过阈值即触发系统保护(取值范围 0.0-1.0),比较灵敏。 - **平均 RT**:当单台机器上所有入口流量的平均 RT 达到阈值即触发系统保护,单位是毫秒。 - **并发线程数**:当单台机器上所有入口流量的并发线程数达到阈值即触发系统保护。 - **入口 QPS**:当单台机器上所有入口流量的 QPS 达到阈值即触发系统保护。 #### 4.3 案例 > 配置全局QPS:系统中的所有接口QPS不能大于1  不管是/testA还是/testB 只要QPS > 1 整个系统就不能用。 这个粒度太粗,就相当于一个窗口人很多,整个银行就不接待人了,不太建议使用。
标签:
SpringCloudAlibaba
,
Sentinel
非特殊说明,本博所有文章均为博主原创。
如若转载,请注明出处:
https://lilinchao.com/archives/2827.html
上一篇
04.Sentinel降级规则
下一篇
IDEA编译运行Spark源码
取消回复
评论啦~
提交评论
栏目分类
随笔
2
Java
326
大数据
229
工具
31
其它
25
GO
40
标签云
SQL练习题
Hbase
微服务
Livy
Stream流
SpringCloudAlibaba
Spark Core
Yarn
Scala
机器学习
nginx
哈希表
Java
Java工具类
Kafka
并发编程
Jquery
MyBatis-Plus
Flink
持有对象
Spark Streaming
MySQL
前端
ajax
Elasticsearch
JavaWeb
工具
Spark RDD
稀疏数组
SpringCloud
友情链接
申请
范明明
庄严博客
Mx
陶小桃Blog
虫洞