我使用的是亚马逊产品广告API,其限制为1 query per second
。我找到了这个图书馆,它似乎可以满足我的要求,但对我的要求来说有点过头了。
有没有一种更简单的方法可以在不使用任何库的情况下限制速率(我正在调用一个函数),除了使用sleep
之外,因为它会为1 second
和我需要发出的请求量休眠,我应该保存每一秒。
$array = range(1,100);
foreach ($array as $value) {
$timestamp = time();
if ($timestamp != time()) {
echo "'n value: ".$value." ".$timestamp;
} else {
usleep(1000000);
echo "'n value: ".$value." ".$timestamp;
}
}
循环查询列表,但在每个循环中都会获得一个unix时间戳(以秒为单位),并且只有在时间戳高于上次发送查询时才发送查询,然后记录时间戳以在下一个循环中进行检查。
如果你的目标是确保你每秒发送的信息不会超过一次,但你不想超过几秒,那么循环可能比If so更好:
foreach ($array as $value) {
$timestamp = time();
while ($timestamp == time()) {
continue;
}
doYourThing();
}
因此,脚本将在您的列表中循环,但对于列表中的每个项目,它将继续在while循环中旋转,直到第二个循环结束,它将执行您的命令并直接进入下一个项目。
您还需要在进程之间共享状态来共享速率。我建议使用我的库:带宽节流/令牌桶
$storage = new FileStorage(__DIR__ . "/api.bucket");
$rate = new Rate(1, Rate::SECOND);
$bucket = new TokenBucket(1, $rate, $storage);
$consumer = new BlockingConsumer($bucket);
$bucket->bootstrap(1);
// This will block all your processes to an effective rate of 1/s
$consumer->consume(1);
echo $productApi->doSomething();
$i=1;
foreach ($array as $value) {
if($i==1) $timestamp = time();
doYourThing();
if($i==5){
while ($timestamp == time()) {
continue;
}
$i=0;
}
$i++;
}
我将@Horaland代码修改为每秒5 doYourThing()
的速率限制。