PHP 中的节流/速率限制

Throttling / Rate Limiting in PHP

我正在使用亚马逊产品广告 API,其限制为 1 query per second。我发现这个 library 似乎可以满足我的要求,但对我的要求来说有点矫枉过正。

除了使用 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 时间戳(以秒为单位),只有当时间戳高于你上次发送查询时才发送查询,然后记录时间戳以供检查在下一个循环中。

如果您的目标是确保您不会每秒发送一次,但又不想浪费时间,那么循环可能比以下情况更好:

foreach ($array as $value) {
  $timestamp = time();
  while ($timestamp == time()) { 
   continue;
  } 
  doYourThing();
}

因此脚本将循环遍历您的列表,但对于列表中的每个项目,它将继续在 while 循环中旋转,直到第二个滴答结束时它将执行您的命令并直接进入下一个项目。

您还需要进程之间的共享状态来共享速率。我建议使用我的图书馆:bandwidth-throttle/token-bucket

$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() 的速率限制。