Win32上的PHP 5.5.3 - cURL需要400ms +来解析所有域名,甚至是localhost

时间:2013-09-19 06:58:38

标签: php curl

自从我将服务器从PHP 5.3.x升级到PHP 5.5.3以来,我遇到了PHP Web服务客户端的问题。

我有这个函数来计算cURL执行请求所需的时间:

function makeRequest($method, $uri) {
    global $requests;

    addTime("makeRequest");

    $curl = curl_init($uri);

    curl_setopt($curl, CURLOPT_HEADER    , true ); 
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true );
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true );
    curl_setopt($curl, CURLOPT_MAXREDIRS     , 10   );

    curl_setopt($curl, CURLOPT_CUSTOMREQUEST , $method);

    //////////////////////////////

    addTime("curl_exec");
    $responseContent = curl_exec($curl);
    remTime("curl_exec");

    addTime("curl_getInfo");
    $responseInfo = curl_getinfo($curl);
    remTime("curl_getInfo");

    array_push( $requests, var_export( $responseInfo, true ) );

    remTime("makeRequest");
}

addTimeremTime是记录microtime(true)以准确衡量方法执行的函数。我也记录curl_getinfo报告的不同时间。见下文。

我尝试了一堆不同的URI。这些是我的结果:

https://api1.mywebservice.com/methodCall

  • total_time - 0.406
  • namelookup_time - 0.0406
  • connect_time - 0.406
  • pretransfer_time - 0.406
  • starttransfer_time - 0.406
  • redirect_time - 0

makeRequest时间: 0.402

https://api2.mywebservice.com/methodCall

api2.mywebservice.com被硬编码到机器的%windir%\system32\drivers\etc\hosts文件中127.0.0.1,所以它永远不会打到DNS服务器

  • total_time - 0.406
  • namelookup_time - 0.0406
  • connect_time - 0.0406
  • pretransfer_time - 0.0406
  • starttransfer_time - 0.0406
  • redirect_time - 0

makeRequest时间: 0.402

https://localhost/methodCall

  • total_time - 0.406
  • namelookup_time - 0.406
  • connect_time - 0.406
  • pretransfer_time - 0.406
  • starttransfer_time - 0.406
  • redirect_time - 0

makeRequest时间: 0.403

https://127.0.01/methodCall

  • total_time - 0
  • namelookup_time - 0
  • connect_time - 0
  • pretransfer_time - 0
  • starttransfer_time - 0
  • redirect_time - 0

makeRequest时间: 0.006

服务器的DNS服务器只有大约5毫秒的距离,但无论如何都应该缓存该名称。 api2.mywebservice.com获得相同时间的事实表明,它不是DNS服务器超时的问题,而是在cURL内部发生了腐烂。

我也试过CURLOPT_RESOLVE,但没有效果:

curl_setopt( $c, CURLOPT_RESOLVE, array("api1.mywebservice.com:443:127.0.01") );

为什么cURL在最新的(也是最好的,肯定?)版本的PHP中需要很长时间来检索结果?

1 个答案:

答案 0 :(得分:2)

您的libcurl似乎是使用它自己的名称解析程序而不是系统名称解析程序构建的。在这种情况下,它根本不使用hosts文件。

有三种可能的解决方案:

  1. 更新你的php_curl.dll(当前windows php二进制文件5.5.4);
  2. 安装本地DNS服务器并将其配置为使用hosts文件,并将您的网络配置为使用127.0.0.1作为DNS服务器;
  3. 将CURLOPT_DNS_USE_GLOBAL_CACHE设置为true(默认情况下处于开启状态),将CURLOPT_DNS_CACHE_TIMEOUT设置为更大的值(默认为2分钟);
  4. 另外:来自php.net的php 5.5.4 windows二进制文件使用系统解析器进行curl。它使用内部缓存(当使用CURLOPT_DNS_USE_GLOBAL_CACHE时)和系统DNS缓存。我已经通过一些测试检查了它。 A还通过curl检查了名称解析的速度 - 它与localhost相同(对于在hosts文件中写入的任何记录)。所以,我绝对不知道它不是一个PHP问题:

    1. https://127.0.01/methodCall中的错误必须是https://127.0.0.1/methodCall。在这种情况下,curl总是返回total_time = 0.
    2. 首先尝试请求静态内容,如空文件,并使用http而不是https。
    3. 禁用所有防火墙并卸载所有防病毒软件(在某些情况下不会停止使用防病毒软件)。
    4. 检查网络服务器的虚拟主机配置,并查看您要求的内容。
    5. 检查curl_getinfo($curl)的所有字段,尤其是"primary_ip"