Sentinel的限流(QPS、线程数、关联、预热、排队等待)热点key,参数例外项

谁借莪1个温暖的怀抱¢ 2022-10-28 03:38 161阅读 0赞

整个项目请看gitee:https://gitee.com/xwb1056481167/spring-cloud

sentinel的安装和项目集成:https://blog.csdn.net/www1056481167/article/details/113679945

流控规则

  • 资源名: 唯一名称,默认请求路径
  • 针对来源: Sentinel可以战队调用者进行限流,填写服务名。默认为default(不区分来源)
  • 阈值类型/单击阈值

    • QPS(每秒中的请求数量): 当调用该api的QPS达到阈值的时候,进行限流
    • 线程数: 当调用该api的线程数达到阈值的时候,进行限流
  • 是否集群: 不需要集群
  • 流控模式:

    • 直连: api达到限流条件时,直接限流
    • 关联: 当关联的资源达到阈值的时候,就限流自己
    • 链路: 指记录指定链路上的流量(指定资源从入口资源进来的流量,如果达到阈值,如果达到阈值,就进行限流)【api级别的针对来源】
  • 流控效果:

    • 快速失败: 直接失败,抛异常 + Warm Up: 根据codeFactor(冷加载因子,默认为3)的值,从阈值/codeFactor,经过预热时长,才打到设置的QPS的阈值。
    • 匀速排队: 匀速排队,让请求以匀速的速度通过,阈值类型必须设置为QPS,否则无效。

Sentinel的限流

配置(以下的testA,testB都是项目cloudalibaba-sentinel-service8401的接口

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3d3dzEwNTY0ODExNjc_size_16_color_FFFFFF_t_70

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3d3dzEwNTY0ODExNjc_size_16_color_FFFFFF_t_70 1

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3d3dzEwNTY0ODExNjc_size_16_color_FFFFFF_t_70 2

1、QPS

每秒中的请求次数超过设定的阈值的时候,进行限流

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3d3dzEwNTY0ODExNjc_size_16_color_FFFFFF_t_70 3

202102051033027.png

2、线程数

原理: 当调用该api的线程数达到设定的阈值,进行限流
类似于在银行办业务,同一个窗口同一时间只有一个客户在办理,其他客户必须等该客户办理完之后才可以办理

如何演示:
1、设置testB的方法执行时间超过1秒,如下

  1. @GetMapping("/testB")
  2. public String testB() {
  3. try {
  4. Thread.sleep(2000);
  5. } catch (InterruptedException e) {
  6. e.printStackTrace();
  7. }
  8. return "-----------testB";
  9. }

2、设置线程数请求阈值

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3d3dzEwNTY0ODExNjc_size_16_color_FFFFFF_t_70 4

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3d3dzEwNTY0ODExNjc_size_16_color_FFFFFF_t_70 5

调用该api的方法/testB只支持一个线程,但是连续访问刷新线程数超过1个就报异常

3、关联

当关联的资源达到阈值的时候,就限流自己
eg:当与A关联的资源B达到阈值后,就限流A自己

jmeter下载地址https://archive.apache.org/dist/jmeter/source/#sig

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3d3dzEwNTY0ODExNjc_size_16_color_FFFFFF_t_70 6

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3d3dzEwNTY0ODExNjc_size_16_color_FFFFFF_t_70 7

访问:ApacheJMeter.jar测试testB接口,然后此时访问testB接口出现一下结果

202102051033027.png

4、预热

根据codeFactor(冷加载因子,默认为3)的值,从阈值/codeFactor,经过预热时长,才打到设置的QPS的阈值。
如:秒杀系统开启的瞬间,会有很多流量上来,很有可能会把系统打死,预热方式就是为了把系统保护起来, 可慢慢的吧流量放进来,慢慢的把阈值增加到设定的值

默认的codeFactor为3,即请求QPS从(threshold/3)开始,经过多少预热后才逐渐升至设定的QPS的阈值 案例:阈值10+预热时常设置5秒 系统初始化的阈值为10/3约等于3,即阈值刚开始为3,经过了5秒后阈值才慢慢升高到10

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3d3dzEwNTY0ODExNjc_size_16_color_FFFFFF_t_70 8
如何测试结果:
刚开始狂点testA,会发现报错Blocked by Sentinel (flow limiting),然后5秒后,阈值从3->10后,会发现狂点刷新浏览器不会出现限流

5、排队等待

让请求以均匀的请求速度通过,阈值类型必须为QPS,否则无效
设定含义/testA每秒1次请求,请超时的话需要排队等待,等待的超时时间为2000毫秒(即2秒)

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3d3dzEwNTY0ODExNjc_size_16_color_FFFFFF_t_70 9

浏览器一直刷新请求testB(服务被限流)

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3d3dzEwNTY0ODExNjc_size_16_color_FFFFFF_t_70 10

热点key限流

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

比如:
商品 ID 为参数,统计一段时间内最常购买的商品 ID 并进行限制
用户 ID 为参数,针对一段时间内频繁访问的用户 ID 进行限制
热点参数限流会统计传入参数中的热点参数,并根据配置的限流阈值与模式,对包含热点参数的资源调用进行限流。热点参数限流可以看做是一种特殊的流量控制,仅对包含热点参数的资源调用生效。

1、测试类 @SentinelResource

  1. @GetMapping("/testHotKey")
  2. @SentinelResource(value = "testHotKey", blockHandler = "deal_testHotKey")
  3. public String testHotKey(@RequestParam(value = "p1", required = false) String p1,
  4. @RequestParam(value = "p2", required = false) String p2) {
  5. return "------------------testHotKey";
  6. }
  7. public String deal_testHotKey(String p1, String p2, BlockException blockException) {
  8. //sentinel 系统默认的提示,Blocked by sentinel (flow limiting)
  9. return "------deal_testHotKey ☹- _ -☹";
  10. }

2、配置热点key接口 资源名必须和@SentinelResource的value相同

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3d3dzEwNTY0ODExNjc_size_16_color_FFFFFF_t_70 11

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3d3dzEwNTY0ODExNjc_size_16_color_FFFFFF_t_70 12

特别注意的是,如果设置了热点限流,后端的controller的方法必须有一个blockHandler方法,如果没有,则直接返回错误页面,

原理分析:网页端设置了testHotKey方法的热点限流,然后对应方法也进行了@SentinelResource注解,但是没有指定具体的blockHandler方法,所以当p1传递了参数, 并且在浏览器端的刷新次数达到了一秒钟2次的话,达到了针对testHotKey的热点限流,此时要执行该热点限流指定的blockHandler, 但是却发现没有,此时就会报错误页面的错

参数例外项

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3d3dzEwNTY0ODExNjc_size_16_color_FFFFFF_t_70 13

参数下标为第0个的参数(后台接收的时候知道是String,需要选择对应的数据类型),正常情况下QPS阈值为1,超过马上被限流,但是如果p1的参数值是5(p1=5)的时候,他的QPS阈值为200。
注意:

@SentinelResource处理的是Sentinel控制台配置的违规情况,有blockHandler方法配置的兜底处理。
RuntimeException int a=10/0,这个处理的是java运行时候的异常,走的是RuntimeException,所以此时@SentinelResource不管
@SentinelResource只管配置出错,运行出错走的是异常

发表评论

表情:
评论列表 (有 0 条评论,161人围观)

还没有评论,来说两句吧...

相关阅读