PHP的cURL扩展的各类响应时间

版权声明:本文为博主原创文章,转载私信或邮箱[email protected]备注用途,通过后方可转载,否则必究!!! https://blog.csdn.net/BlackButton_CC/article/details/73476978

  说实话,PHP官方手册对CURL的几个响应时间说明,如total_time、namelookup_time等,十分之模糊,让人摸不着头脑。这篇博文特此图文详细说明了这几个常用的响应时间,为了需要用到这几个响应时间,但是不知该怎么用的同僚。

1. PHP中的cURL

  首先,curl、libcurl和cURL是截然不同的3个东西。

  curl是利用URL语法在命令行方式下工作的开源文件传输工具。它是命令行工具,可以通过shell或脚本来运行curl。curl底层所使用的库是libcurl。curl是瑞典curl组织开发的,可以从官网获取它的源代码和相关说明。
  libcurl是一个库,通常与别的程序绑定在一起使用,如命令行工具curl就是封装了libcurl库。所以我们也可以在你自己的程序或项目中使用libcurl以获得类似CURL的强大功能。它可以跨平台,如Windows、Linux、Unix,也可以与许多语言相结合,如PHP、C++。在官网获得其源码和文档。
  cURL通常用作PHP中libcurl扩展的名字,这个扩展确保了PHP程序员在程序中可以访问libcurl库所提供的功能,所以cURL其实封装了libcurl。

2. cURL中各响应时间的翻译

  我直接翻译的是liburl的官方文档,原因上面已经陈述过。

  • CURLINFO_FILETIME

    • 用一个long型指针储存接收文档的远程的时间(以秒的形式,从1970年1月1号的GMT/UTC时区起)。如果你值为-1,可能是因为许多原因(服务器隐藏了时间或不支持获取文档时间等)和接收文件的时间未知。
    • Pass a pointer to a long to receive the remote time of the retrieved document (in number of seconds since 1 jan 1970 in the GMT/UTC time zone). If you get -1, it can be because of many reasons (it might be unknown, the server might hide it or the server doesn’t support the command that tells document time etc) and the time of the document is unknown.
  • CURLINFO_TOTAL_TIME

    • 用一个double型指针储存用秒计的上一次传输的总共的时间,包括域名解析,TCP连接等。double类型表示含有小数且以秒记的时间。
    • Pass a pointer to a double to receive the total time in seconds for the previous transfer, including name resolving, TCP connect etc. The double represents the time in seconds, including fractions.
  • CURLINFO_NAMELOOKUP_TIME(这里的解释就清晰很多了)

    • 用一个double型的指针储存用秒计的从最开始到域名解析完毕的总共的时间。
    • Pass a pointer to a double to receive the total time in seconds from the start until the name resolving was completed.
  • CURLINFO_CONNECT_TIME

    • 用一个double型的指针储存用秒计的从最开始到与远程主机(或代理)的连接完毕。
    • Pass a pointer to a double to receive the total time in seconds from the start until the connection to the remote host (or proxy) was completed.
  • CURLINFO_APPCONNECT_TIME

    • 用一个double型的指针储存以秒计的时间,它包含了从最开始直到SSL/SSH与远程主机连接/握手完毕。这个时间经常非常接近CURLINFO_PRETRANSFER_TIME,除了这种情况之外,比如HTTP管线化时,pretransfer time将会因为在通道中排队或者其他原因而延时。
      注:HTTP管线化是将多个HTTP要求(request)整批提交的技术)
    • Pass a pointer to a double to receive the time, in seconds, it took from the start until the SSL/SSH connect/handshake to the remote host was completed. This time is most often very near to the CURLINFO_PRETRANSFER_TIME time, except for cases such as HTTP pipelining where the pretransfer time can be delayed due to waits in line for the pipeline and more.
  • CURLINFO_PRETRANSFER_TIME

    • 用一个double型的指针储存以秒计的时间,它包含从最开始到文件刚刚开始传输的时间。这个时间包含了所有的pre-transfer命令和针对独特的协议们的协商。它不包含用于触发传输的request专用协议的发送。
    • Pass a pointer to a double to receive the time, in seconds, it took from the start until the file transfer is just about to begin. This includes all pre-transfer commands and negotiations that are specific to the particular protocol(s) involved. It does not involve the sending of the protocol- specific request that triggers a transfer.
  • CURLINFO_STARTTRANSFER_TIME

    • 用一个double类型的指针储存以秒计的时间,它包含了从最开始直到第一个字节被libcurl收到的时间。它包含了CURLINFO_PRETRANSFER_TIME时间和服务器去计算结果的时间。
    • Pass a pointer to a double to receive the time, in seconds, it took from the start until the first byte is received by libcurl. This includes CURLINFO_PRETRANSFER_TIME and also the time the server needs to calculate the result.
  • CURLINFO_REDIRECT_TIME

    • 用一个double类型的指针储存以秒计的时间,它包含了所有重定向步骤的时间,包括域名解析、连接、传输前(pretransfer)和在最后的一次传输开始之前。它包含了多重重定向的完整的执行时间。
    • Pass a pointer to a double to receive the total time, in seconds, it took for all redirection steps include name lookup, connect, pretransfer and transfer before final transaction was started. CURLINFO_REDIRECT_TIME contains the complete execution time for multiple redirections.

3. 各响应时间的模型

模型图
  上图为我自身总结的各响应时间组成的简要模型,比如,namelookup_time指的是域名解析完毕时所在的整个HTTP请求的位置。

4. 测试代码和结果

  在这部分展示测试代码和结果,以及一些疑问。

class Main {
    public function curl($url) {
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER , 1);
        curl_setopt($ch, CURLOPT_TIMEOUT, 5);
        curl_exec($ch);
        $info = curl_getinfo($ch);
        $this->printTime($info);
    }

    public function printTime($curlInfo) {
        $total_time = $curlInfo['total_time'];      //获得用秒表示的上一次传输总共的时间,包括DNS解析、TCP连接等。
        $namelookup_time = $curlInfo['namelookup_time'];      //获得用秒表示的从最开始到域名解析完毕的时间。
        $connect_time = $curlInfo['connect_time'];      //获得用秒表示的从最开始直到对远程主机(或代理)的连接完毕的时间。
        $pretransfer_time = $curlInfo['pretransfer_time'];      //获得用秒表示的从最开始直到文件刚刚开始传输的时间。
        $starttransfer_time = $curlInfo['starttransfer_time'];      //获得用秒表示的从最开始到第一个字节被curl收到的时间。
        $redirect_time = $curlInfo['redirect_time'];      //获得所有用秒表示的包含了所有重定向步骤的时间,包括DNS解析、连接、传输前(pretransfer)和在最后的一次传输开始之前。

        echo "1. 总共的传输时间(total_time)为:" . $total_time . " 秒\n";

        echo "2. 直到DNS解析完成时间(namelookup_time)为:" . $namelookup_time . " 秒\n";

        echo "3. 建立连接时间(connect_time)为:" . $connect_time . " 秒\n";

        echo "4. 传输前耗时(pretransfer_time)为:" . $pretransfer_time . " 秒\n";

        echo "5. 开始传输(starttransfer_time)为:" . $starttransfer_time . " 秒\n";

        echo "6. 重定向时间(redirect_time)为:" . $redirect_time . " 秒\n";

    }
}
$url1 = "http://finance.sina.com.cn/";     //访问“新浪财经”域名
$url2 = "http://111.73.45.199:8090/b1/%E9%87%91%E5%88%9A%E7%8B%BC3%EF%BC%9A%E6%AE%8A%E6%AD%BB%E4%B8%80%E6%88%98.Logan.2017.1080p.WEB-DL.DD5.1.H264-%E4%B8%AD%E6%96%87%E5%AD%97%E5%B9%95-RARBT.torrent";        //这是电影的种子,直接访问服务器,无DNS解析时间。
$test = new Main();
$test->curl($url1);
$test->curl($url2);

访问“新浪财经”的结果:
访问“新浪财经”的结果

访问”种子文件“的结果:
访问”种子文件“的结果

疑问:
1.为什么每次3和4,即connect_time和pretransfer_time都一样呢?
答:经过思考和查阅libcurl源代码,结合官方的解释(它包含从最开始到文件刚刚开始传输的时间)与自身的测试(“3.连接耗时”和“4.传输前耗时”总是一样),这个pretransfer_time肯定 不是 指服务器处理request请求后,刚准备要发送文件的那一刻,因为这样的话,“连接耗时”和“传输前耗时”必然不会一样。
  那么,pretransfer_time指的是什么?。总所周知,在HTTP请求中有3次TCP传输,完成第2次传输时,就完成了与服务器的连接,这个时间点就是connect_time的值。结合官方的解释 (This includes all pre-transfer commands and negotiations that are specific to the particular protocol(s) involved. It does not involve the sending of the protocol- specific request that triggers a transfer) 可知,这个pretransfer_time 不包括请求的requst的协议时间,那么pretransfer_time指的就是HTTP请求中,TCP第3次传输的那一刻。这也刚好解释了”为什么每次3和4”都一样的现象。
  总结,pretransfer_time真正指的是一次HTTP请求中,第3次TCP报文发送的时刻。

2.为什么PHP官方网页的对pretransfer_time的翻译为“从建立连接到准备传输所使用的时间 ”?
答:官网链接为http://php.net/manual/zh/function.curl-getinfo.php。在英文页面中,我们看到pretransfer_time的解释为 Time in seconds from start until just before file transfer begins,这与我的在libcurl的官方解释看到的一致。然而,中文页面解释为 从建立连接到准备传输所使用的时间,中文解释中的”建立连接“应该改为”从最开始“。
  结论,PHP官方网页中,对cURL中各变量的中文解释有误。

参考文献

[1] 《curl和libcurl的区别简介》
[2] 《官方回复STARTTRANSFER_TIME和PRETRANSFER_TIME的区别》
[3] 《DNS解析过程示意图》

猜你喜欢

转载自blog.csdn.net/BlackButton_CC/article/details/73476978