我正在尝试对我的客户端api调用实现速率限制。因为每15分钟大约有20个Symfony2命令使用相同的api(限制为10reqs/sec),所以我需要使用RabbitMQ,这样我的进程就不会耗尽内存,也不会阻止下一个进程正常执行。
由于api调用是在命令和RabbitMQ工作线程中执行的,因此我也需要在RabbitMQ中限制它们。我知道在我的情况下,工人不应该做这样的工作,但我没有时间重构整个事情。
那么,有没有可能限制我的RabbitMQ工作者中所有这些命令的通用方法呢?我正在尝试使用https://github.com/jaytaph/RateLimitBundle和https://github.com/snc/SncRedisBundle (在我的系统上安装并运行了predis库和Redis ),但我有点卡住了。
当速率限制接近最大值时,我该如何处理?我需要一个事件监听器吗?我是否必须检查Redis的速率限制,如果它是近距离接触节流?
我的方法如下所示
/**
* @RateLimit(limit=10, period=60)
*/
protected function apiRequest($query)
{
$url = $this->getApiUrl().$query.$this->getUsernameAndApiKey();
echo $url. "\r\n";
$xml = $this->getWithCurl($url);
$xml = simplexml_load_string($xml);
// if ($xml === false) {
// $this->slack->sendMessage($this->getError($url));
// }
if($xml)
return $xml;
}
Redis配置:
snc_redis:
clients:
default:
type: predis
alias: default
dsn: redis://localhost
速率限制配置:
noxlogic_rate_limit:
enabled: true
storage_engine: "redis"
redis_client: default
rate_response_code: 429
rate_response_exception: Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException
display_headers: true
headers:
limit: X-RateLimit-Limit
remaining: X-RateLimit-Remaining
reset: X-RateLimit-Reset
发布于 2017-02-13 16:30:10
只需使用INCRBY
Redis命令(https://redis.io/commands/incrby)即可。命令的响应将是递增后的值,因此在代码中,您可以将此值与您的限制进行比较,如下所示:
$counter = $redis->increment($key);
if ($counter > $limit) {
//deny logic here
}
由于Redis的单线程原子特性,它将处理许多并发请求,因此处理的请求不会超过$limit。
https://stackoverflow.com/questions/42117795
复制