PHP - curl_exec 需要 100 毫秒

Posted

技术标签:

【中文标题】PHP - curl_exec 需要 100 毫秒【英文标题】:PHP - curl_exec taking 100ms 【发布时间】:2012-02-29 19:26:25 【问题描述】:

我的 php 项目通过使用 curl 从 WCF RESTful Web 服务获取数据来工作。

但是,由于某种原因,curl_exec 函数总是需要大约 100 毫秒才能返回,即使 WCF Web 服务在同一台机器上,并且被调用的 WCF 服务函数只需要 3 毫秒即可执行。

我分析了 WCF 服务,整个 WCF 堆栈接受 HTTP 请求并在 10 毫秒内返回生成的 XML(一个包含 5 个元素的微小 XML 结构)。

以下是我的 cURL 设置代码:

    $curl = curl_init($this->uri);

    curl_setopt($curl, CURLOPT_HEADER        , true ); // return response HTTP headers in output
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true ); // return result instead of echoing
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // stop cURL from verifying the peer's certificate. This is set because by default (and right now) cURL does not trust /any/ certificate.
    curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true ); // follow redirects, Location: headers (but does it really?)
    curl_setopt($curl, CURLOPT_MAXREDIRS     , 10   ); // but dont redirect more than 10 times

    curl_setopt($curl, CURLOPT_CUSTOMREQUEST , $this->method );

    if( isset( $this->username  ) )
        curl_setopt($curl, CURLOPT_USERPWD  , $this->username . ':' . $this->password );

    if( isset( $this->userAgent ) )
        curl_setopt($curl, CURLOPT_USERAGENT, $this->userAgent);

    if( isset( $this->content ) ) 
        curl_setopt($curl, CURLOPT_POSTFIELDS, $this->content );

        array_push( $this->headers, 'Content-Length: '. $this->contentLength );

        if( isset( $this->contentType ) )
            array_push( $this->headers, 'Content-Type: ' . $this->contentType );
    

    if( isset( $this->contentFile ) ) 
        curl_setopt($curl, CURLOPT_INFILE    , $this->contentFile   );
        curl_setopt($curl, CURLOPT_INFILESIZE, $this->contentLength );
        array_push( $this->headers, 'Content-Length: '. $this->contentLength );
        array_push( $this->headers, 'Content-Type: '  . $this->contentType );
    

    if( count( $this->headers ) > 0 )
        curl_setopt($curl, CURLOPT_HTTPHEADER, $this->headers );

对 curl_exec 的调用立即发生在这段代码之后,并且我始终以 100 毫秒测量的是 curl_exec 调用。

降低这个 PHP 站点的加载时间很重要,但我不明白为什么会发生这种情况。

更新:

无论请求什么,cURL 的 curl_exec 似乎总是需要 100 毫秒,尽管非常有趣的是,当我发出第二个 curl_exec 请求(在同一个 PHP 页面执行中)它完成得更快 - 大约 20 毫秒。

谜团加深。

更新 2:

我意识到 curl_getinfo() 返回一个包含时序信息的关联数组。当我从第一个 cURL 请求中转储信息时,我看到以下内容:

'total_time' => 0.125,
'namelookup_time' => 0.125,
'connect_time' => 0.125,
'pretransfer_time' => 0.125,
'starttransfer_time' => 0.125,

而所有后续请求都是这样(或更好):

'total_time' => 0.016,
'namelookup_time' => 0,
'connect_time' => 0,
'pretransfer_time' => 0,
'starttransfer_time' => 0.016,

似乎延迟是在名称查找中,但我不知道为什么 DNS 查找需要这么长时间,因为 Windows(服务器操作系统)已经缓存了 DNS 信息并且其他应用程序(桌面、ASP.NET 等)可以在 1 毫秒内解析名称,但 cURL 在 125 毫秒内完成。

cURL 有什么特别之处,它不能使用操作系统的 DNS 缓存?

【问题讨论】:

开销、连接、TCP、HTTP 协议等。为什么在本地服务时使用 HTTP 请求?难道没有另一种更快的方法吗?请记住,您对 WCF 服务的分析可能是在所有令人讨厌的连接和 HTTP 业务已经进行了一段时间之后开始的...... wrikken 的 cmets 也是如此。您在计时计算中忽略了整个 TCP/HTTP 开销——如何将 curl 命中计时到完全没有服务的页面?与您的 WCF 响应之一大小相同的简单静态 html 页面,并查看 curl 需要多长时间。如果它也是 100 毫秒,那么它不是 wcf,它更卷曲/开销。 如果在同一台机器上,为什么不直接从其他系统的数据库中读取呢? 我做了检查 - cURL 查询似乎总是需要大约 100 毫秒,即使对于同一服务器上的静态 HTML 文件和网络中其他地方的服务器也是如此。但是,辅助请求要快得多 - 这表明这与 cURL 有关。 您是否检查过诸如 DNS 查找延迟之类的内容? 【参考方案1】:

我认为这是我的 PHP 安装中包含的 cURL 版本中的错误。在我将 cURL(和 PHP)更新到更新版本后,问题消失了,curl_exec 现在在 20 毫秒内执行。

【讨论】:

能否告诉我们,您之前使用的是哪个版本?【参考方案2】:

确保您要连接的域在您的服务器主机文件中。如果 curl 没有在调用之间缓存结果,则 100 毫秒可能是 DNS 查找时间。

【讨论】:

以上是关于PHP - curl_exec 需要 100 毫秒的主要内容,如果未能解决你的问题,请参考以下文章

XAMPP 在 Windows 上的 PHP 运行速度太慢了 100 倍

PHP中的curl_exec

php 中 怎么让curl_exec 以数组形式返回

PHP Curl PUT 在 curl_exec 处停止

php file_get_contents 和 curl_exec 不适用于外部文件

php 中 怎么让curl_exec 以数组形式返回