渔民/令牌桶

此包已被废弃且不再维护。作者建议使用 symfony/rate-limiter 包。

令牌桶算法的实现。

3.0.0 2020-07-15 20:15 UTC

This package is auto-updated.

Last update: 2024-02-13 16:50:14 UTC


README

注意

此项目已归档。请实现更近期的 symfony/rate-limiter。它也实现了令牌桶算法,并享有更好的支持。

令牌桶

这是对 bandwidth-throttle/token-bucket 的分支,最初创建是为了添加对 zend-cache(现在为 laminas-cache)的支持。

这是 PHP 中 令牌桶算法 的线程安全实现。您可以使用令牌桶来限制资源的使用率。(例如,流带宽或 API 使用。)

令牌桶是一个抽象的隐喻,可以应用于资源消费和生产的节流。例如,您可以限制第三方 API 的消费率,或者您还可以限制他人使用您资源的使用率。

安装

使用 Composer

composer require jouwweb/token-bucket

示例

此示例将限制全局资源的使用率为每秒 10 个请求。

use JouwWeb\TokenBucket\Rate;
use JouwWeb\TokenBucket\TokenBucket;
use JouwWeb\TokenBucket\storage\FileStorage;

$storage = new FileStorage(__DIR__ . "/api.bucket");
$rate = new Rate(10, Rate::SECOND);
$bucket = new TokenBucket(10, $rate, $storage);
$bucket->bootstrap(10);

if (!$bucket->consume(1, $seconds)) {
    http_response_code(429);
    header(sprintf("Retry-After: %d", floor($seconds)));
    exit();
}

echo "API response";

注意:在此示例中,TokenBucket::bootstrap() 是代码的一部分。这不建议在生产环境中使用,因为这会产生不必要的存储通信。应将 TokenBucket::bootstrap() 作为应用程序的引导过程或部署过程的一部分,以提供初始可用令牌的数量。

BlockingConsumer

在示例中,我们或处理请求或以 HTTP 状态码 429 失败。这是一种非常高效的请求节流方式,但有时可能希望不失败而是等待请求通过。您可以通过使用 BlockingConsumer 实例来消费令牌桶来实现这一点。

use JouwWeb\TokenBucket\BlockingConsumer;
/** @var \JouwWeb\TokenBucket\TokenBucket $bucket */

$consumer = new BlockingConsumer($bucket);

// This will block until one token is available.
$consumer->consume(1);

echo "API response";

将此添加到上一个示例将有效地将速率限制为每秒 10 个请求。然而,客户端不必处理 429 错误,而是有时需要等待更长一段时间。