PHP中的节流/速率限制


Throttling / Rate Limiting in PHP

我使用的是亚马逊产品广告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()的速率限制。