【问题标题】:Should I close cURL or not?我应该关闭 cURL 吗?
【发布时间】:2013-08-05 11:30:57
【问题描述】:

我有一个函数可以多次使用 cURL 调用 3 个不同的 API。每个 API 的结果都会传递给嵌套循环中调用的下一个 API,因此 cURL 当前打开和关闭超过 500 次。

我应该让 cURL 对整个函数保持打开状态,还是可以在一个函数中多次打开和关闭它?

【问题讨论】:

  • 相当模糊的问题,没有看到用法以及如何处理代码。
  • 我倾向于在可靠性方面犯错,并且新句柄似乎不太成问题,因为如果您创建一个新句柄,请求的剩余状态似乎不太可能污染未来的请求。话虽如此,我有一个定期运行数周的进程,在同一个 curl 句柄上发出近百万个 http 请求。它们是对单个域上单个 api 的非常简单的 http 请求。我没有遇到任何问题。
  • 小心使用它通过 curl(post、put 等)更改数据,因为它可以在后台重用旧数据,请参阅我的回答:stackoverflow.com/a/67266458/4699609

标签: php performance curl


【解决方案1】:

重复使用同一个句柄可以提高性能。见:Reusing the same curl handle. Big performance increase?

如果您不需要同步请求,请考虑使用 curl_multi_* 函数(例如 curl_multi_initcurl_multi_exec 等),这也可以大幅提升性能。

更新:

我尝试通过为每个请求使用新句柄并使用具有以下代码的相同句柄来代替 curl:

ob_start(); //Trying to avoid setting as many curl options as possible
$start_time = microtime(true);
for ($i = 0; $i < 100; ++$i) {
    $rand = rand();
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, "http://www.google.com/?rand=" . $rand);
    curl_exec($ch);
    curl_close($ch);
}
$end_time = microtime(true);
ob_end_clean();
echo 'Curl without handle reuse: ' . ($end_time - $start_time) . '<br>';

ob_start(); //Trying to avoid setting as many curl options as possible
$start_time = microtime(true);
$ch = curl_init();
for ($i = 0; $i < 100; ++$i) {
    $rand = rand();
    curl_setopt($ch, CURLOPT_URL, "http://www.google.com/?rand=" . $rand);
    curl_exec($ch);
}
curl_close($ch);
$end_time = microtime(true);
ob_end_clean();
echo 'Curl with handle reuse: ' . ($end_time - $start_time) . '<br>';

得到以下结果:

Curl without handle reuse: 8.5690529346466
Curl with handle reuse: 5.3703031539917

因此,当多次连接到同一个服务器时,重复使用同一个句柄实际上可以显着提高性能。我尝试连接到不同的服务器:

$url_arr = array(
    'http://www.google.com/',
    'http://www.bing.com/',
    'http://www.yahoo.com/',
    'http://www.slashdot.org/',
    'http://www.stackoverflow.com/',
    'http://github.com/',
    'http://www.harvard.edu/',
    'http://www.gamefaqs.com/',
    'http://www.mangaupdates.com/',
    'http://www.cnn.com/'
);
ob_start(); //Trying to avoid setting as many curl options as possible
$start_time = microtime(true);
foreach ($url_arr as $url) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_exec($ch);
    curl_close($ch);
}
$end_time = microtime(true);
ob_end_clean();
echo 'Curl without handle reuse: ' . ($end_time - $start_time) . '<br>';

ob_start(); //Trying to avoid setting as many curl options as possible
$start_time = microtime(true);
$ch = curl_init();
foreach ($url_arr as $url) {
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_exec($ch);
}
curl_close($ch);
$end_time = microtime(true);
ob_end_clean();
echo 'Curl with handle reuse: ' . ($end_time - $start_time) . '<br>';

得到以下结果:

Curl without handle reuse: 3.7672290802002
Curl with handle reuse: 3.0146431922913

仍然有相当大的性能提升。

【讨论】:

  • 我想知道 curl 是否使用了 keep-alive 连接。仅此一项就可以解释大部分性能提升。
  • 我相信 cURL 使用 keep-alive,但是每次调用 curl_exec() 都会发起一个新的请求(因为选项可能已经改变等),尤其是在连接到不同的服务器时,这必须是案子。
  • 谢谢大家。虽然我连接到同一台服务器但 URL 不同,但我对 Otome 发布的基准感到惊讶。但是我真的很喜欢克里斯发布的可靠性点.....
  • 虽然我意识到这是一篇旧文章,但对于不同服务器的基准测试要记住的一点是,DNS 查找必须在第一次执行的时间范围内发生,从而使结果中毒。如果您在同一个文件中运行一个简单的测试副本(只需复制和粘贴几次),您会注意到性能最终大致相当。
猜你喜欢
  • 2011-09-01
  • 2023-01-06
  • 1970-01-01
  • 2018-07-02
  • 1970-01-01
  • 2019-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多