curl_multi_getcontent从1000多个url返回随机NULL值

时间:2014-02-19 11:33:32

标签: php multithreading curl

我在从数据库生成的几个url中使用多curl检索json数据时出现问题,如果我将查询限制在100到500个链接,则问题不会发生,但是当链接达到1000+时,即时启动从curl_multi_getcontent获得随机NULL返回。

多卷曲功能:

function curlMultiExec($nodes)
{     
  $node_count = count($nodes);     
  $ch_arr = array();

  $master = curl_multi_init();

  for($i = 0; $i < $node_count; $i++)
  {
      $url        = $nodes[$i]['url'];
      $ch_arr[$i] = curl_init($url);

      curl_setopt($ch_arr[$i], CURLOPT_RETURNTRANSFER, TRUE);  
      curl_setopt($ch_arr[$i], CURLOPT_BINARYTRANSFER, TRUE);
      curl_setopt($ch_arr[$i], CURLOPT_FOLLOWLOCATION, TRUE);  
      curl_setopt($ch_arr[$i], CURLOPT_AUTOREFERER,    TRUE); 
      curl_setopt($ch_arr[$i], CURLOPT_HEADER,         FALSE);
      curl_multi_add_handle($master, $ch_arr[$i]);
  }

  $running = null;
  do 
  {
    curl_multi_exec($master,$running);
  } while( $running > 0 );


  $obj = array();
  for($i = 0; $i < $node_count; $i++ )
  {
       $item = array(              
           'url'        => $nodes[$i]['url'],
           'content'    => curl_multi_getcontent($ch_arr[$i])              
        ); 
        array_push($obj, $item);       
}        
curl_multi_close($master);  
return $obj;
}

目前$nodes[$i]['url']包含1,912个网址。

使用print_r

的输出
Array
    (
       [0] => Array
       (
        [url] => http://api.worldbank.org/countries/AFG/indicators/NY.GDP.MKTP.CD?per_page=100&date=1960:2014&format=json
        [content] => [{ /* json data */ }]
    )

[1] => Array
  (
        [url] => http://api.worldbank.org/countries/ALB/indicators/NY.GDP.MKTP.CD?per_page=100&date=1960:2014&format=json
        [content] =>   // -> here's the sample null value
  )

  .
  .  //-> and some random [content] here also contains null value 
  .
  .
  [1191] => Array
  (
        [url] => http://api.worldbank.org/countries/ZWE/indicators/NY.GDP.MKTP.CD?per_page=100&date=1960:2014&format=json
        [content] => [{ /* json data */ }]
  )
)

请告诉我为什么它会返回随机空值,或者是什么导致了这种行为,还是有更好的方法呢?


更新(2014-02-20);  我在这里找到了解决方案:curl_multi() without blocking

问题是curl_multi的大多数实现在处理它们之前等待每组请求完成。如果要求立即处理的请求太多,它们通常会分组,然后一次处理一个。

解决方案是在完成后立即处理每个请求。这消除了繁忙等待时浪费的CPU周期。

基于他的方法,我成功地解决了这个问题。也许这篇文章可以提供帮助,以防有人绊倒同样的问题。

干杯!

1 个答案:

答案 0 :(得分:1)

1000个同时连接很容易让你达到最大打开文件/套接字数量的公共限制:1024。这可能是你在这里点击的。

有关如何更改限制的相关问题:How do I change the number of open files limit in Linux?