【发布时间】:2018-01-15 00:27:13
【问题描述】:
这实际上是继上一个问题之后的一个问题,不幸的是,我没有收到任何答案,所以我并没有完全屏住呼吸等待回复,但我知道这可能是一个需要解决的棘手问题。
我目前正在尝试对外部 API 的传出请求实施速率限制,以匹配其端的限制。我试图在我们用来管理这个特定 API 的 Guzzle 请求的类中实现一个令牌桶库 (https://github.com/bandwidth-throttle/token-bucket)。
最初,这似乎按预期工作,但我们现在开始看到来自 API 的 429 响应,因为它似乎不再正确地限制请求的速率。
我感觉正在发生的事情是,由于 Symfony 处理服务的方式,每次调用 API 时,桶中的令牌数量都会被重置。
我正在设置当前在服务的构造函数中设置存储桶位置、速率和起始数量:
public function __construct()
{
$storage = new FileStorage(__DIR__ . "/api.bucket");
$rate = new Rate(50, Rate::MINUTE);
$bucket = new TokenBucket(50, $rate, $storage);
$this->consumer = new BlockingConsumer($bucket);
$bucket->bootstrap(50);
}
然后我尝试在每个请求之前使用令牌:
public function fetch(): array
{
try {
$this->consumer->consume(1);
$response = $this->client->request(
'GET', $this->buildQuery(), [
'query' => array_merge($this->params, ['api_key' => $this->apiKey]),
'headers' => [ 'Content-type' => 'application/json' ]
]
);
} catch (ServerException $e) {
// Process Server Exception
} catch (ClientException $e) {
// Process Client Exception
}
return $this->checkResponse($response);
}
我看不到任何明显的东西,这将允许它每分钟请求超过 50 次,除非每个请求都重置可用令牌的数量。
这被提供给一组存储库服务,这些存储库服务处理将来自每个端点的数据转换为系统内使用的对象。消费者使用适当的存储库来请求完成其流程所需的数据。
如果令牌的数量被服务构造函数中的引导函数重置,那么应该将其移动到 Symfony 框架中仍可与消费者一起使用的哪个位置?
【问题讨论】:
标签: php symfony guzzle rate-limiting