限流策略和流控效果

Sentinel 支持三种不同的限流策略,分别是直接流控、关联流控和链路流控。下面将结合实际的配置页面详细讲解这三种流控方式各自的使用场景。

限流策略之直接流控

直接流控就相当于直接作用于当前设置的资源上,如果访问压力的值大于设定值,后续的请求就会被 Sentinel 拦截。

下面讲解在 Sentinel 控制台中配置一条直接流控规则的步骤。

在左侧导航栏中能够看到所有已经接入 Sentinel 的应用。单击 newbee-cloud-order-service 下的 “簇点链路”,就能够看到当前应用下的所有资源,如图 11-9 所示。

image 2025 04 18 12 37 39 965
Figure 1. 图11-9 newbee-cloud-order-service 服务端“簇点链路”页面

如果运行本节代码后没有看到图 11-9 中的数据,就只需要对这些请求发起调用,之后会触发信息上报,等待几秒再刷新页面,就可以看到这些信息了。其实可以在每个资源的列表栏中直接单击 “流控” 按钮来给资源添加流控规则。

另一种配置流控规则常用的方式是在流控规则页面中操作。单击左侧菜单栏中的 “流控规则”,进入流控规则页面,单击右上角的 “新增流控规则” 按钮,之后会弹出 “新增流控规则” 对话框,在这里把相关的属性添加进去,最后单击 “新增” 按钮就能够完成流控规则的配置了,过程如图 11-10 所示。

image 2025 04 18 12 38 25 972
Figure 2. 图11-10 新增流控规则的过程展示

在这里,笔者给 “order/saveOrder” 这个资源新增一条直接限流的规则。设置 QPS 为限流阈值类型,一旦对该资源的请求 QPS>2,就会触发限流。

限流策略之关联流控

当两个资源之间具有资源争抢或依赖关系时,这两个资源便有了关联。与直接流控直接作用到当前资源本身的情况略有不同,关联流控是对两个资源进行流控配置,对资源1做出是否超过阈值的判断,最终的流控效果作用于资源2,通常用于存在竞争或不同优先级的场景中。

这里以 /order/testRelateApi1/order/testRelateApi2 为例来讲解和演示关联流控,假设这两个资源有竞争关系,并且 /order/testRelateApi1 资源的优先级高于 /order/testRelateApi2 资源的优先级。在这种情况下,就可以对低优先级的资源实施限流,配置细节如图 11-11 所示。

image 2025 04 18 12 39 33 881
Figure 3. 图11-11 流控的关联规则配置示例

在 “新增流控规则” 对话框中,新增了一条针对 /order/testRelateApi2 资源的流控规则,流控模式选择的是 “关联”,而关联资源是 /order/testRelateApi1。同时,设置了 QPS 为限流阈值类型,一旦对 /order/testRelateApi1 资源的请求 QPS>3,就会触发对 /order/testRelateApi2 资源的限流。

这里需要读者重点关注的是,关联限流的阈值判断是作用于高优先级资源上的,但是流控效果作用于低优先级资源上,这种流控模式更注重两个资源之间的优先级问题。

限流策略之链路流控

在一个应用中,对同一个资源有多条不同的访问链路,如果想对某一条访问链路进行限流,就可以选择 “链路流控” 模式。如图 11-12 所示,资源 /testChainApi1 和资源 /testChainApi2 的请求都调用了资源 getNumber(),而 Sentinel 是允许只根据某个入口的统计信息对资源限流的,这样就可以实现更加细粒度的限流了。

image 2025 04 18 12 41 44 079
Figure 4. 图11-12 链路流控示意图

具体到本节的源码,/order/testChainApi1/order/testChainApi2 这两个接口都调用了同一个方法 getNumber(),同时该方法也被标示为一个资源(使用了 @SentinelResource 注解)。如果想实现只对来自 /order/testChainApi1 接口的请求进行限流,那么就可以将链路流控应用在 getNumber() 上,同时指定当前流控规则的 “入口资源” 是 /order/testChainApi1,配置细节如图 11-13 所示。

image 2025 04 18 12 42 29 246
Figure 5. 图11-13 流控的链路规则配置示例

在 “新增流控规则” 对话框中,新增了一条针对 getNumber() 资源的流控规则,流控模式选择的是 “链路”,而入口资源是 /order/testChainApi1。同时,设置了 QPS 为限流阈值类型,一旦对 getNumber() 资源的请求 QPS>1,同时该请求来源是 /order/testChainApi1,就会触发对 getNumber() 资源的限流。

这里的限流配置只对 /order/testChainApi1 接口有影响,对 /order/testChainApi2 接口是没有任何影响的。通俗地说,这种流控模式是一种 “双标行为”,一旦设置后只对某一个入口进行统计和限流,QPS 一旦达到 1 就会触发限流。而对另一个入口是完全没有影响的,即使 QPS 达到 10000,这条链路也是完全正常的。

另外,需要注意的是,如果想使链路流控策略生效,就需要在配置文件中添加如下配置项:

spring.cloud.sentinel.web-context-unify=false

否则即使配置了链路流控的规则,也无法生效。

介绍完流控策略之后,接下来介绍 Sentinel 中的流控效果配置。Sentinel 支持三种流控效果,分别是快速失败、Warm Up 和排队等待。其实流控效果的配置在前文中的配置截图中都能看到,只不过笔者在演示时统一选择的是默认的 “快速失败”。

流控效果之快速失败

Sentinel 默认的流控效果是快速失败,前文中在配置流控规则时都采用了这种模式。这种流控效果非常好理解,当 QPS 超过任意规则的阈值后,新的请求就会被立即拒绝,拒绝方式为抛出 FlowException 异常。

Sentinel 文档中也把默认的方式称为 “直接拒绝”,和快速失败是一个含义,都表示 Sentinel 默认的流控效果。

流控效果之Warm Up

Warm Up 即预热/冷启动方式。系统长期处于流量平缓的状态,当出现流量激增的情况时,直接让系统按照设定的阈值处理请求可能会把系统压垮。通过预热/冷启动方式让通过的流量缓慢增加,在一定时间内逐渐增加到阈值上限,给系统一个预热的时间。处理请求的数量慢慢地增多,经过预热的时间后,到达系统处理请求个数的最大值。Warm Up 方式就是为了实现这个目的。

举个例子,在 “新增流控规则” 对话框中设置的系统阈值(QPS)为 20,预热时间为 10 秒,如图 11-14 所示。

image 2025 04 18 12 45 51 965
Figure 6. 图11-14 流控的预热效果配置示例

那么 Sentinel 会在这 10 秒的预热时间内将限流阈值从 7 缓慢拉高到 20。下面的代码是某次使用 Warm Up 方式的限流日志:

0 send qps is: 3699
1656316625000, total:3699, pass:7, block:3692
1 send qps is: 3898
1656316626000, total:3898, pass:7, block:3893
2 send qps is: 3713
1656316627000, total:3713, pass:7, block:3708
3 send qps is: 3756
1656316628000, total:3756, pass:8, block:3749
4 send qps is: 3750
1656316629000, total:3750, pass:9, block:3741
5 send qps is: 3492
1656316630000, total:3492, pass:10, block:3482
6 send qps is: 3923
1656316631000, total:3923, pass:11, block:3913
7 send qps is: 3176
1656316632000, total:3176, pass:13, block:3163
8 send qps is: 3729
1656316633000, total:3729, pass:18, block:3711
9 send qps is: 3534
1656316634000, total:3534, pass:20, block:3514
10 send qps is: 3611
1656316635000, total:3611, pass:20, block:3591

每秒的请求数都在 3000 个以上,而一开始限流在 7 个左右,其他的请求都会被拦截,慢慢地涨到 10 个、13 个,到第 10 秒的时候,系统开始稳定地处理所设置的阈值——20 个请求。

至于起始阈值是 7,是因为冷启动方式下有一个计算公式:起始阈值=单机阈值/冷加载因子。查看源码可知,冷加载因子为 3,源码如下(com.alibaba.csp.sentinel.slots.block.flow.controller.WarmUpController):

public WarmUpController(double count, int warmUpPeriodInSec) {
  this.construct(count, warmUpPeriodInSec, 3);
}

流控效果之排队等待

排队等待方式会严格控制请求通过的间隔时间,让请求以均匀的速度通过。排队等待方式有两个重要的点,其一是匀速,其二是排队。

image 2025 04 18 12 51 57 956
Figure 7. 图11-15 排队等待效果的示意图

QPS 设置为 2,表示 1 秒内允许 2 个请求通过,排队等待方式会控制请求通过的间隔,即每 1000/2=500 毫秒通过一个请求,如图 11-15 所示。如果将 QPS 设置为 10,则表示1秒内允许 10 个请求通过,即每 100 毫秒通过一个请求。

超出 QPS 阈值的请求不会立即失败,而是被放入一个队列,排好队等待被处理。然而,一旦请求在队列中等待的时间超过了设置的超时时间,请求就会触发限流。

要设置匀速排队的流控效果,可以在 “新增流控规则” 对话框中进行设置,如设置 QPS 为 10、超时时间为 1000 毫秒,如图 11-16 所示。

image 2025 04 18 12 52 38 334
Figure 8. 图11-16 流控的排队等待效果配置示例

另外,排队等待方式暂时不支持 QPS>1000 的场景。

规则配置及限流效果展示

本节将通过实际的限流规则演示来对 Sentinel 流量控制知识做总结。

  1. 直接流控和 Warm Up

    下面演示直接流控策略和 Warm Up 流控效果的流控规则。进入 Sentinel 控制台新增一条规则,配置细节如图 11-17 所示。

    image 2025 04 18 12 53 29 684
    Figure 9. 图11-17 直接流控策略和 Warm Up 流控效果的配置示例

    在这里,笔者给 “order/saveOrder” 资源新增了一条直接限流的规则。设置 QPS 为限流阈值类型,一旦对该资源的请求 QPS>6,就会触发限流。限流效果为 Warm Up,以预热的方式缓慢拉高限流阈值。

    规则添加成功后,就可以打开浏览器或其他工具发起请求,对 Sentinel 的限流功能进行测试。在浏览器的地址栏中输入如下请求 URL

    http://localhost:8187/order/saveOrder?cartId=3&goodsId=102

    笔者是直接在浏览器中测试的,比较直观,用重复刷新页面的方式模拟多次发送请求。读者在测试时也可以使用这种方式,还可以使用 JMeter 等工具来发送请求并查看效果。

    图 11-18 为正常访问情况下和被限流后的响应信息。

    image 2025 04 18 12 54 56 877
    Figure 10. 图11-18 正常访问情况下和被限流后的响应信息

    可以看出该流控规则已经生效了,请求一旦超出阈值就会被限流。不过,这里配置的 WarmUp 流控效果与快速失败流控效果不同,它有一个缓慢拉升 QPS 阈值的过程,也就是说一开始被限流的请求会更多,可以查看 Sentinel 控制台中的实时监控页面,如图 11-19 所示。

    image 2025 04 18 12 55 30 720
    Figure 11. 图11-19 配置流控为直接流控策略和 Warm Up 流控效果后的请求实时监控页面

    与预期效果一致,刚开始被限流的数量会多一些,经过一段时间后才会按照 QPS 阈值数限流。读者在测试时可以用不同的流控效果对比一下。

  2. 关联流控和快速失败

    接下来演示关联流控策略和快速失败流控效果的流控规则。进入 Sentinel 控制台,新增一条规则,配置细节如图 11-20 所示。

    这里新增了一条针对 /order/testRelateApi2 资源的流控规则,流控模式选择的是 “关联”,而关联资源是 /order/testRelateApi1。同时,设置了 QPS 为限流阈值类型,一旦对 /order/testRelateApi1 资源的请求 QPS>2,就会触发对 /order/testRelateApi2 资源的限流。

    image 2025 04 18 12 57 50 487
    Figure 12. 图11-20 关联流控策略和快速失败流控效果的配置示例

    规则添加成功后,可以打开浏览器或其他工具发起请求,对 Sentinel 的限流功能进行测试。在浏览器地址栏中输入如下请求 URL

    http://localhost:8187/order/testRelateApi1
    http://localhost:8187/order/testRelateApi2

    图11-21 是 testRelateApi1 接口未超过 QPS 阈值情况下两个接口的响应数据,一切正常。

    image 2025 04 18 13 00 11 509
    Figure 13. 图11-21 配置流控为关联流控策略和快速失败流控效果后的请求响应结果1

    图11-22是 testRelateApi1 接口超过 QPS 阈值情况下两个接口的响应数据,testRelateApi1 接口正常,而 testRelateApi2 接口被流控。

    image 2025 04 18 13 00 39 962
    Figure 14. 图11-22 配置流控为关联流控策略和快速失败流控效果后的请求响应结果2

    通过查看 Sentinel 控制台中的实时监控页面会更加直观,如图 11-23 所示。

    image 2025 04 18 13 02 49 556
    Figure 15. 图11-23 配置流控为关联流控策略和快速失败流控效果后的请求实时监控页面

    testRelateApi1 接口的访问一直被通过,而 testRelateApi2 接口则被流控规则限制,一旦 testRelateApi1 接口的 QPS 达到 2,对 testRelateApi2 接口的请求就会直接拒绝。

由于篇幅有限,这里只展示了部分规则的配置和最后的流控效果,读者可以在此基础上对其他的规则进行配置并查看其流控效果。

本节主要讲解 Sentinel 的三大流控模式,分别是直接流控、关联流控和链路流控,以及三种流控效果,分别是快速失败、Warm Up 和排队等待。同时,笔者也通过实际的示例讲解了流控规则该如何配置,相信读者已经对 Sentinel 的各种流控效果有了比较全面的了解。接下来将讲解 Sentinel 的另一个最常用的稳定性保障手段——降级熔断。