【问题标题】:Am I thinking about Redis::throttle correctly?我是否正确考虑 Redis::throttle ?
【发布时间】:2020-05-03 03:06:25
【问题描述】:

我在我的 laravel 应用程序中使用 Redis::throttle 来限制对各种 Web 服务的请求,但我们以亚马逊为例。

如果亚马逊文档说特定用户可以使用具有以下漏桶限制的特定端点:允许 40 个请求,在初始 40 个之后每半秒允许一个新请求。

然后我会让我的Redis::throttle 看起来像这样:

    $key = 'Amazon|'.$requestType.'|'.$user->id;
    Redis::throttle($key)->allow(40)->every(20)->then(function () {
        // Job logic...
    });

每 20 秒允许 40 个请求似乎是漏桶的定义方式。但这样对吗?

因为我想,替代方案就是我每秒允许 2 个请求

Redis::throttle($key)->allow(2)->every(1)

但这不允许爆发 40 次。

【问题讨论】:

    标签: laravel throttling


    【解决方案1】:

    当您执行Redis::throttle($key)->allow(40)->every(20) 时,我查看了信息是如何存储的,并发现了以下内容:

    它以秒为单位存储两个时间戳,一个“开始”和一个“结束”。 'start' 将是第一次在该键上调用 'throttle' 时的时间戳,而 'end' 将是开始时间戳 + ->every() 中的任何值

    1) "start"
    2) "1579168555"
    3) "end"
    4) "1579168575"
    5) "count"
    6) "1"
    

    因此,在这种情况下,开始为 1579168555,结束为 1579168575

    然后它还存储一个计数,每次后续调用都会递增,直到时间戳通过,然后它会删除之前的开始/结束/计数并开始一个新的。

    关于漏桶的问题是,它实际上允许您执行以下操作:

    • 在时间戳 1579168555 发出 1 个请求
    • 等待 15 秒,然后在时间戳 1579168570 发出 39 个请求
    • 再等 6 秒,现在 Throttle 键被清除,现在可以发出 40 个请求

    但最后两步会是短时间内79个请求,这是不允许的。

    所以我实际上最好做一些类似Redis::throttle($key)->allow(2)->every(1) 的事情,现在允许爆发。 throttle 接口并没有完全实现漏桶逻辑,但它允许您以至少让您与漏桶兼容的方式对其进行节流。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-01-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多