重用cURL多处理程序中的句柄


Reusing handles from cURL multi handler

好吧,我正试图重用我在初始过程中生成的句柄,但在第一次运行后,它就停止了工作。如果我删除(或重新创建整个处理程序)句柄并再次添加它们,效果会很好。这件事的罪魁祸首是什么?

我的代码目前看起来是这样的:

<?php
echo 'Handler amount: ';
$threads = (int) trim(fgets(STDIN));
if($threads < 1) {
    $threads = 1;
}
$s = microtime(true);
$url = 'http://mywebsite.com/some-script.php';
$mh = curl_multi_init();
$ch = array();
for($i = 0; $i < $threads; $i++) {
    $ch[$i] = curl_init($url);
    curl_setopt_array($ch[$i], array(
        CURLOPT_USERAGENT => 'Mozilla/5.0 (X11; Linux i686; rv:21.0) Gecko/20130213 Firefox/21.0',
        CURLOPT_REFERER => $url,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_NOBODY => true
    ));
    curl_multi_add_handle($mh, $ch[$i]);
}
while($mh) {
    $running = null;
    do {
        curl_multi_exec($mh, $running);
    } while($running > 0);
    $e = microtime(true);
    $totalTime = number_format($e - $s, 2);
    if($totalTime >= 1) {
        echo floor($threads / $totalTime) . ' requests per second (total time '.$totalTime.'s)' . "'r";
        $s = microtime(true);
    }
}
foreach($ch as $handler) {
    curl_multi_remove_handle($mh, $handler);
    curl_close($handler);
}
curl_multi_close($mh);
?>

当我将CURLOPT_VERBOSE设置为true时,我看到许多"额外的东西不能精细传输。c:1037:00"消息,我在另一个问题上读到了这些消息,似乎是由一些明显的事情引起的:

  • 过快

  • 防火墙

  • ISP限制

AFAIK,事实并非如此,因为如果我每次都重新创建句柄,它们将以每秒79个请求(每个请求约529字节)的成功完成

我重复使用手柄的过程:

  1. 创建多处理程序,并将指定数量的处理程序添加到多处理程序

  2. 当mutli处理程序工作时,执行的所有处理程序

  3. while循环停止后(似乎不太可能),关闭所有句柄和多卷曲处理程序

它执行所有句柄一次,然后停止。

这真是难住我了。有什么想法吗?

我遇到了同样的问题(不过使用C++),发现我需要删除curl easy句柄并重新添加它。我的解决方案是删除curl_multi_perform循环末尾的所有句柄,并将它们添加回外循环的开头,在外循环中我重用现有的保活连接:

for(;;) // loop using keep-alive connections
{
    curl_multi_add_handle(...)
    while ( stillRunning ) // curl_multi_perform loop 
    {
        ...
        curl_multi_perform(...)
        ...
    }
    curl_multi_remove_handle(...)
}

也许这也适用于您的PHP场景。请记住:不要将curl_easy_cleanupcurl_easy_init作为介于两者之间的卷曲手柄。

如果您打开CURLOPT_VERBOSE,您可以在控制台中跟随,并且您的连接确实得到了重用。这为我解决了这个问题。