有没有办法限制(有延迟)向外部服务器传出的 PHP+curl 请求,以便每秒只有 n 个请求?PHP 在 Fastcgi 模式下使用,因此无法使用睡眠。
问问题
3881 次
2 回答
1
是的。有 curl 多处理程序...
(您可以使用此库以 OOP 方式进行操作)
例如:
// Creates the curl multi handle
$mh = curl_multi_init();
$handles = array();
foreach($urls as $url)
{
// Create a new single curl handle
$ch = curl_init();
// Set options
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 300);
// Add to the multi handle
curl_multi_add_handle($mh,$ch);
// Put the handles in an array to loop this later on
$handles[] = $ch;
}
// Execute the multi handle
$running=null;
do
{
$mrc = curl_multi_exec($mh,$running);
// Added a usleep for 0.50 seconds to reduce load
usleep (250000);
}
while($running > 0);
// Get the content of the urls (if there is any)
$output = array();
for($i=0; $i<count($handles); $i++)
{
// Get the content of the handle
$content = curl_multi_getcontent($handles[$i]);
$output[] = $content;
if($printOutput) {
echo $content;
}
// Remove the handle from the multi handle
curl_multi_remove_handle($mh,$handles[$i]);
}
// close the multi curl handle to free system resources
curl_multi_close($mh);
于 2012-09-10T19:48:41.420 回答
1
您可以使用令牌桶算法控制速率。当您想控制一个资源的所有 PHP 进程的速率时,您需要共享存储桶的状态。您可以使用我的实现以线程安全的方式执行此操作:bandwidth-throttle/token-bucket
use bandwidthThrottle\tokenBucket\Rate;
use bandwidthThrottle\tokenBucket\TokenBucket;
use bandwidthThrottle\tokenBucket\BlockingConsumer;
use bandwidthThrottle\tokenBucket\storage\FileStorage;
$storage = new FileStorage(__DIR__ . "/api.bucket");
$rate = new Rate(10, Rate::SECOND);
$bucket = new TokenBucket(10, $rate, $storage);
$consumer = new BlockingConsumer($bucket);
$bucket->bootstrap(10);
// This blocks all processes to the rate of 10 requests/second
$consumer->consume(1);
$api->doSomething();
于 2015-07-12T18:42:10.637 回答