【问题标题】:Making multiple curl requests without timeout.在没有超时的情况下发出多个 curl 请求。
【发布时间】:2016-05-29 09:50:48
【问题描述】:

我正在开发一个系统,我需要使用多个 GET 请求获取 5000 多个用户的位置。不幸的是,API 端点不支持多个客户端 ID。 IE。我必须发出 5000 多个唯一的 get 请求来获取它们的位置并使用(累积响应)进行另一个 API 调用。

我正在使用 CURL 发出请求。我使用以下 sn-p[1] 提出请求。

<?php

function multiRequest($data, $options = array()) {

  // array of curl handles
  $curly = array();
  // data to be returned
  $result = array();

  // multi handle
  $mh = curl_multi_init();

  // loop through $data and create curl handles
  // then add them to the multi-handle
  foreach ($data as $id => $d) {

    $curly[$id] = curl_init();

    $url = (is_array($d) && !empty($d['url'])) ? $d['url'] : $d;
    curl_setopt($curly[$id], CURLOPT_URL,            $url);
    curl_setopt($curly[$id], CURLOPT_HEADER,         0);
    curl_setopt($curly[$id], CURLOPT_RETURNTRANSFER, 1);

    // post?
    if (is_array($d)) {
      if (!empty($d['post'])) {
        curl_setopt($curly[$id], CURLOPT_POST,       1);
        curl_setopt($curly[$id], CURLOPT_POSTFIELDS, $d['post']);
      }
    }

    // extra options?
    if (!empty($options)) {
      curl_setopt_array($curly[$id], $options);
    }

    curl_multi_add_handle($mh, $curly[$id]);
  }

  // execute the handles
  $running = null;
  do {
    curl_multi_exec($mh, $running);
  } while($running > 0);


  // get content and remove handles
  foreach($curly as $id => $c) {
    $result[$id] = curl_multi_getcontent($c);
    curl_multi_remove_handle($mh, $c);
  }

  // all done
  curl_multi_close($mh);

  return $result;
}

?>

它非常适合少量请求,但是当我尝试达到 1000+ 时,它会超时。

    $data = [];

    for ($i = 0; $i < 1000; $i++) {
        $data[] = 'https://foo.bar/api/loc/v/queries/location?address=XXXXXXXXX';

    }
    $token = $this->refresh();

    $r = $this->multiRequest($data, $token);

解决此问题的最佳方法是什么?

  • 一个。增加 PHP 脚本的 maximum_execution_time 或
  • 乙。使用多线程之类的东西或
  • c。其他

【问题讨论】:

  • 在PHP中使用线程并不完美,容易出现请求瓶颈,使系统不稳定。我认为好的解决方案是一个队列(例如:RabbitMQ)+ java 进程(或 nodejs)来支持 php 发出多个请求。你可以限制这个进程的请求,多线程,控制内存。重要的是使用 PHP for web 分离任务保持流畅运行。

标签: php curl


【解决方案1】:

有没有办法修改端点 API 以允许处理多个 id?如果是,那是首选,因为如果您同时运行数千个请求,您实际上会进行 DDoS 攻击。

但是,您可能需要检查 PHP 的 curl_multi_* 函数 (http://us3.php.net/manual/en/function.curl-multi-exec.php)。

另一个有用的链接:http://www.onlineaspect.com/2009/01/26/how-to-use-curl_multi-without-blocking/

【讨论】:

  • 无法修改 API 端点(不在我的控制范围内)。我实际上是在代码中使用 curl_multi_* 函数。
  • 有没有办法捕捉用户位置变化事件并在位置变化时动态更新?
  • 嗯,不。如果我想这样做,我想再次投票。
  • 好的。位置是否经常变化?也许您可以分部分处理任务(例如在一天中)?
  • 是的。位置确实经常变化。但拉取地点的要求通常很紧急。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-08
相关资源
最近更新 更多