jouwweb/token-bucket

该包已被弃用,不再维护。作者建议使用 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 中 Token Bucket 算法 的线程安全实现。您可以使用令牌桶来限制资源的使用率。(例如,流带宽或 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 错误,而是有时需要等待更长一些。