【问题标题】:cURL slow starttransfer_timecURL 慢启动传输时间
【发布时间】:2013-12-24 02:00:31
【问题描述】:

美好的一天!

cURL 在请求页面时表现非常缓慢。我知道它不是请求的页面,因为页面会立即在浏览器中返回。

我注意到的两件事

  • starttransfer_time 通常接近 20
  • local_port 似乎每次都在变化。这正常吗?
  • 有时,cURL 会立即响应

我有以下代码:

$ch = curl_init(); 
curl_setopt($ch, CURLOPT_URL, $url ); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, false);
$output = curl_exec($ch); 
curl_close($ch); 

回应 curl_getinfo() 给了我以下信息

[url] => http://127.0.0.1:80/wpengine/?json=t
[content_type] => text/html; charset=iso-8859-1
[http_code] => 302
[header_size] => 215
[request_size] => 64
[filetime] => -1
[ssl_verify_result] => 0
[redirect_count] => 0
[total_time] => 17.238
[namelookup_time] => 0
[connect_time] => 0
[pretransfer_time] => 0
[size_upload] => 0
[size_download] => 221
[speed_download] => 12
[speed_upload] => 0
[download_content_length] => 221
[upload_content_length] => 0
[starttransfer_time] => 17.238
[redirect_time] => 0
[certinfo] => Array
    (
    )

[primary_ip] => 127.0.0.1
[primary_port] => 80
[local_ip] => 127.0.0.1
[local_port] => 51875
[redirect_url] => 

谁能给我一些关于如何弄清楚发生了什么的指示?

这里有几行来自 Apache 访问日志

127.0.0.1 - - [06/Dec/2013:12:01:22 -0500] "GET /wpengine/?json=t HTTP/1.1" 302 221
127.0.0.1 - - [06/Dec/2013:12:01:12 -0500] "GET /community HTTP/1.1" 200 6266
127.0.0.1 - - [06/Dec/2013:12:01:22 -0500] "GET /public/js/jquery.js?b=10 HTTP/1.1" 304 -

【问题讨论】:

  • 如果你在本地运行这个,你设置了什么服务器?你能检查一下服务器日志吗?
  • @r3mus 我正在使用 Apache 运行 Wamp。我编辑了我的帖子以包含访问日志中的几行
  • 好奇 CURL 是否首先尝试 IPv6,但未能解决?尝试添加curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4 );
  • 嗯,这并没有什么不同。我觉得这很令人费解。它是否与会话有关,因为它位于同一域中?只是在黑暗中开枪......
  • 不太确定,但是看看你的日志,一旦 CURL 真正命中服务器,它就超级快了。有什么方法可以在某处的公共服务器上尝试此操作以消除 localhost 变量?

标签: php performance curl


【解决方案1】:

这主要是因为Expect: 100-continue header CURL在处理大量POST数据时发送给服务器,而服务器恰好不支持该功能。您可以通过为curl 命令行添加-vv 来确认并查看输出。

要解决这个问题,你可以

  1. 修复您的服务器以支持Expect: 100-continue 标头,或
  2. 通过添加-H "Expect:"选项强制curl不发送(在php中可以参考这个答案:How can I stop cURL from using 100 Continue?)。

关于Expect: 100-continue的链接:

https://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html#sec8.2.3 https://support.urbanairship.com/entries/59909909--Expect-100-Continue-Issues-and-Risks

【讨论】:

    【解决方案2】:

    我在访问 Google Analytics 的 MP API 时发现了一个类似的问题...... starttransfer 时间始终为 1.0 秒加上一小部分,据此我推断某处存在 1 秒延迟,我猜是 cURL。它最终没有使用 CPU,我不知何故怀疑谷歌是否在延迟......来自 curl_getinfo() 的 otuput ...

    大批 ( [网址] => http://www.google-analytics.com/collect [内容类型] => 图片/gif [http_code] => 200 [header_size] => 388 [请求大小] => 201 [文件时间] => -1 [ssl_verify_result] => 0 [redirect_count] => 0 [总时间] => 1.021528 [namelookup_time] => 8.7E-5 [连接时间] => 8.8E-5 [pretransfer_time] => 0.000324 [大小上传] => 1736 [size_download] => 35 [速度下载] => 34 [速度上传] => 1699 [下载内容长度] => 35 [上传内容长度] => 1736 [starttransfer_time] => 1.002496 [重定向时间] => 0 [certinfo] => 数组 ( ) [redirect_url] => )

    【讨论】:

    • 是的,使用 lwp-request 的快速命令行脚本(为每个 POST 启动一个新的 Perl 解释器)比在一个 PHP 进程中循环的 cURL 快几英里。
    • 我找到了解决此问题的方法,至少满足我的需要......我将上述参数列表传递给 CURLOPT_POSTFIELDS 期望它生成一个 urlencoded 帖子正文,但实际上它会生成多部分。为了让它发送一个普通的 URLencoded POST,你必须自己编码正文参数并传递一个现成的字符串。由于某种原因,多部分进程有一秒钟的延迟,普通的 POST 会全速运行。
    • 是的。尽管我不明白为什么 multipart 需要这么长时间才能开始,但它起作用了,延迟消失了!你真的应该用这个信息更新你的答案
    【解决方案3】:

    @brandonscript 在此线程中的其中一个 cmets 帮助我解决了问题。

    他的回答:

    好奇 CURL 是否先尝试 IPv6,但未能解决?

    尝试添加 curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4 );

    我的问题正好相反,我必须设置以下选项:

    curl_setopt($curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V6 );
    

    谢谢你们,了不起的人。

    【讨论】:

      【解决方案4】:

      我通过设置解决了

      curl_setopt($ch, CURLOPT_POST, false);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-10-01
        • 1970-01-01
        • 2018-03-06
        • 2016-09-01
        • 1970-01-01
        相关资源
        最近更新 更多