【问题标题】:PHP cURL multi_exec delay between requests请求之间的 PHP cURL multi_exec 延迟
【发布时间】:2011-08-08 19:21:05
【问题描述】:

如果我运行一个标准的 cURL_multi_exec 函数(下面的示例),我会立即获得所有请求的 cURL 句柄。我想在每个请求之间延迟 100 毫秒,有没有办法做到这一点? (在 Google 和 StackOverflow 搜索中找不到任何内容)

我在 curl_multi_exec() 之前尝试过 usleep(),它会减慢脚本速度但不会推迟每个请求。

// array of curl handles & results
$curlies = array();
$result = array();
$mh = curl_multi_init();

// setup curl requests
for ($id = 0; $id <= 10; $id += 1) {
    $curlies[$id] = curl_init();
    curl_setopt($curlies[$id], CURLOPT_URL,            "http://google.com");
    curl_setopt($curlies[$id], CURLOPT_HEADER,         0);
    curl_setopt($curlies[$id], CURLOPT_RETURNTRANSFER, 1);
    curl_multi_add_handle($mh, $curlies[$id]);
}

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

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

// all done
curl_multi_close($mh);

我整天都在努力,任何帮助将不胜感激!谢谢。

编辑: 还有其他非 cUrl 方法吗?这也将回答我的问题。

【问题讨论】:

  • 没有。 PHP 的 curl 支持不提供这种功能。
  • 还有其他非 cUrl 方法吗?这也将回答我的问题。谢谢。
  • PHP 根本不是多线程的。您必须并行运行脚本的多个副本。并且脚本的每个副本都将完全独立于其他副本。你必须有一些方法告诉每个脚本它应该获取哪个 url
  • 我知道 cURL multi 只是一个等待所有连接解决的线程。一个线程的类似解决方案将解决我的问题。我不想一次对任何具有 1000 个请求的服务器进行 DDoS,但我也不想一次运行一个请求(太慢)。
  • 所有网址都在一个网站上吗?还是您要访问多个站点?如果是多个,则在每个多线程中点击一个站点,并在整个脚本上暂停 100 毫秒。即使您同时访问 5 或 10 个网站,它也会在每个网站上显示为每 100 毫秒 1 次。

标签: php multithreading curl delay curl-multi


【解决方案1】:

是的,这是可能的。如果您使用ParallelCurl library,您可以更轻松地使用usleep() 添加您的 100 毫秒延迟,因为您可以发出单独的请求以添加到下载队列中。

for ($urls as $url) {
    $pcurl->startRequest($url);
    usleep(100000);
}

【讨论】:

  • 很遗憾,它不起作用。脚本永远挂起,我不是唯一一个报告问题的人:github.com/petewarden/ParallelCurl/issues
  • 很奇怪。也许自从我上次抓住它以来它已经更新了。我现在在 2 个不同的应用程序中使用这种方法,并且没有问题。今晚我会看看我的版本,并发布更新。也许这与我对副本的不同修改有关......
  • 我确认。这种方法完全没有问题。 +1。分叉不能在网络上使用。但是 ParallelCurl 可以在 web 和命令行上运行。
【解决方案2】:

不要以为你可以。如果您从 cli 运行它,您可以将 fork your script 改为 10 个进程,然后从每个进程中触发常规 curl 请求。这将允许您对时间进行细粒度控制。

【讨论】:

【解决方案3】:

PHP 不是解决方案。分叉脚本也无济于事。一开始是的,但是一旦你有更多的网站,你需要像这样抓取你会发现自己作为你的服务器非常非常红。就成本和脚本稳定性而言,您应该重新考虑使用其他想法。

您可以使用 Python 轻松做到这一点,并且在对 API 端点进行非阻塞实时调用的情况下,您应该使用 Socket.IO + Node.JS 或仅 Node.JS 之类的东西,嗯……哈哈

如果你没有时间也不会使用这样的东西:

http://framework.zend.com/manual/en/zendx.console.process.unix.overview.html

这实际上完全取决于您要实现的目标。

【讨论】:

  • 我同意最后一句话 :) 我总是在 ping 同一个服务器 (API)。服务器可以保留请求,但我只想推迟它们而不等待前一个请求完成。
【解决方案4】:

你可以试试这个:
在数据库中存储一个时间戳,添加一个句柄并调用curl_multi_exec
使用CURLOPT_PROGRESSFUNCTION 来检查时间并在需要时添加更多句柄。
Here Daniel Stenberg(cURL 和 libcurl 的作者)表示可以在执行 curl_multi_exec 后添加更多句柄。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-06-26
    • 1970-01-01
    • 2019-02-13
    • 1970-01-01
    • 2022-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多