Sentinel之流控

83 阅读5分钟

如何使用sentinel进行流量控制

前置条件

依赖

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

配置yml

server:
  port: 10001
spring:
  application:
    name: cloud-consumer-feign
  cloud:
    nacos:
      discovery:
        namespace: public
        server-addr: localhost:8848
    //[0]    
    sentinel:
      transport:
        dashboard: localhost:8080
        port: 8719
  • [0]处 为配置sentinel,dashboard时sentinel后台管理页面地址,port为sentinel api 端口
实践—限流配置
  1. 新建一个测试接口
@GetMapping("/testA")
public String testA() {
    return "test A port:" + port;
}
  1. 进入dashboard

浏览器输入上述配置的dashboard地址用户名密码都是 sentinel

image-20220825180029127

先看侧边栏,第一道划线处为当前配置sentinel的服务,看上面 “配置yml” 处配置的spring.apploication.name=cloud-consumer-openfeign就知道为什么这里名字时cloud-consumer-openfeign了。

  1. 点开簇点链路

image-20220825180058233

可以看到这已经有一些请求过来了,还可以看到我们之前测试openfeign时调用的 /consumerHello接口实际时调用了cloud-provider-paymenthello接口

  1. 请求测试接口

  2. 回到后台页面刷新

    可以看到testA接口已经被探测到了,由此可见sentinel他是懒加载的。即只有接口请求之后才会被sentinel发现。

下面我们围绕流控熔断降级热点授权分别举例子来说明

流控
  • 如何添加流控规则

    • 簇点链路界面选择点击接口的流控的按钮

    image-20220825180111203

    • 点击新增或者新增并继续添加,并配置规则(稍后说)

    • 切换到流控规则页面,此时就会多一条流控的规则的信息

      image-20220825180121887

  • 参数说明

    • 回到我们新建流控规则的簇点链路界面。再次点击 “流控” 按钮,我们来看看参数时是什么意思

      image-20220825180131298

      资源名:接口名

      针对来源:Sentinel可以针对调用者进行限流,填写微服务名,指定对哪个微服务进行限流 ,默认default(不区分来源,全部限制)

      阈值类型:

      • QPS: 每秒钟的请求数量,当调用该接口的QPS达到了阈值的时候,进行限流;
      • 并发线程数:当调用该接口的线程数达到阈值时,进行限流

      单机阈值:限流的阈值

      流控模式:

      • 直接:接口达到限流条件时,直接限流
      • 关联:当关联的资源达到阈值时,就限流自己
      • 链路:只记录指定链路上的流量(指定资源从入口资源进来的流量,如果达到阈值,就可以限流)[api级别的针对来源]

      流控效果:

      • 快速失败:直接失败
      • Warm Up:即请求 QPS 从 threshold / 3 开始,经预热时长逐渐升至设定的 QPS 阈值。点击后可以选择预热时长
      • 排队等待:排队等待点击之后可以设置等待时间
  • 如何编辑规则

    image-20220825180246767

    如图直接填写参数就好。

  • QPS模式->直接->直接失败演示

    我们配置限流为 每秒只能请求一次 /testA接口,现在测试。如下图可以看到,当我们请求过快之后,第二次就失败了

    image-20220825180325484

    并且失败之后会有如下字样,这是sentinel自带的失败处理,我们后面可以自定义。

    image-20220825180337068

    选择直接失败就会直接返回如上字样,告知你接口被限流了。

  • QPS模式->直接->warm up演示

    该方式主要用于系统长期处于低水位的情况下,当流量突然增加时,直接把系统拉升到高水位可能瞬间把系统压垮。通过"冷启动",让通过的流量缓慢增加,在一定时间内逐渐增加到阈值上限,给冷系统一个预热的时间,避免冷系统被压垮的情况。

    • 假设我们设置如下

    image-20220825180346853

    阈值:3,预热时长 :6。会限制QPS到3/3次,然后经过6秒之后 加到QPS为3。

    • jmeter配置

      每秒三个请求

      image-20220825180402005

    • 测试结果

    image-20220825180410064

    可以发现很明显的刚开始三个只能成功一个,后面三个就全部成功了。

  • QPS模式->直接->排队等待演示

    • 流控规则配置如下

      image-20220825180424033

    • jmeter配置

      一秒发五个请求

      image-20220825180435423

    • 测试结果

image-20220825180443892

分析一下为什么有一个会失败,因为QPS为3,所以有三个肯定成功,触发排队等待之后。每三分之一秒会处理一个数据。而我们的超时时间500ms

所以最后被后端接受处理的两个请求必定有一个要等待600ms才会被处理。所以就会失败。

注意:图中的顺序并不是,后端处理的顺序。理论上他们是同一时间到达后端的。

  • QPS模式->关联->快速失败演示

    这里我只演示一个剩下的大家举一反三即可

    • 新建关联接口 /testB

      @GetMapping("/testB")
      public String testB() {
          return "test B port:" + port;
      }
      
    • 流控规则配置如下

      • /testA

      image-20220825180455726

      • /testB

      image-20220825180510761

    • jemter配置

      请求 /testB 一秒两次触发限流

      image-20220825180529230

    • 结果

      image-20220825180537347

      可以看见 /testA被限流了,当我们取消调/testA的测试 立马 /testA接口就又好了。

  • QPS模式->链路->快速失败演示

    同样这个模式,我也只演示一个。其他的依然可以举一反三或者通过查文档解决.

    • 流控配置

      这次调用链路为 chain1->chain2->chain3

      image-20220825180549799

      此处入口资源填写来自于簇点链路页面

      image-20220825180557815

      因为chain1被我整合在了gateway服务里面,所以这里看不到。但我们同样可以用这个举例子。

      a->b->d, a->b->e, a->c->f, a->c->g均可视作链路。 假设我以a为入口资源,d为终点资源,对这条链路进行限制的话,则资源a,b,d均会被限制访问。

      同样如果我们对chain2进行了链路流控,则从入口资源chain2的位置的资源就会被限流。

    • 测试

      请求过快会导致限流

      image-20220825180607756

      再来看看chain3则完全不受影响

      image-20220825180614102

      所以链路流控更加像是区间流控,它会限流一个区间。

  • 流控总结

    • 通过页面配置可以完成大部分流控
    • 限流措施又三种直接失败warm up,排队等待
    • 限流阈值类型有两种:QPS并发线程数
    • 限流对象有三种:直接(单点)关联链路(区间)