如何使用cURL一次测量请求和响应时间?

How do I measure request and response times at once using cURL?

我有一个Web服务,它接收JSON格式的数据,处理数据,然后将结果返回给请求者。

我想使用cURL来衡量请求,响应和总时间。

我的示例请求如下:

1
curl -X POST -d @file server:port

我目前在Linux中使用time命令测量它:

1
time curl -X POST -d @file server:port

时间命令只测量总时间 - 这不是我想要的。

有没有办法使用cURL来衡量请求和响应时间?


从这篇精彩的博客文章... https://blog.josephscott.org/2011/10/14/timing-details-with-curl/

cURL支持格式化输出以获取请求的详细信息(有关详细信息,请参阅-w, –write-out 下的cURL联机帮助页)。出于我们的目的,我们将仅关注所提供的时序细节。

  • 创建一个新文件curl-format.txt并粘贴到:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
        time_namelookup:  %{time_namelookup}

           time_connect:  %{time_connect}

        time_appconnect:  %{time_appconnect}

       time_pretransfer:  %{time_pretransfer}

          time_redirect:  %{time_redirect}

     time_starttransfer:  %{time_starttransfer}

                        ----------

             time_total:  %{time_total}
  • 发出请求:

    1
    curl -w"@curl-format.txt" -o /dev/null -s"http://wordpress.com/"

    或者在Windows上,它是......

    1
    curl -w"@curl-format.txt" -o NUL -s"http://wordpress.com/"
  • 这是做什么的:

    -w"@curl-format.txt"告诉cURL使用我们的格式文件
    -o /dev/null将请求的输出重定向到/ dev / null
    -s
    告诉cURL不要显示进度表
    "http://wordpress.com/"
    我们要求的网址。如果您的网址为"&",请使用引号查询字符串参数

    这是你得到的回报:

    1
    2
    3
    4
    5
    6
    7
    8
       time_namelookup:  0.001
          time_connect:  0.037
       time_appconnect:  0.000
      time_pretransfer:  0.037
         time_redirect:  0.000
    time_starttransfer:  0.092
                       ----------
            time_total:  0.164

    创建Windows快捷方式(也称为BAT文件)

    将此命令放在CURLTIME.BAT中(与curl.exe位于同一文件夹中)

    1
    curl -w"@%~dp0curl-format.txt" -o NUL -s %*

    然后你可以简单地打电话......

    1
    curltime wordpress.org


    这是答案:

    1
    curl -X POST -d @file server:port -w %{time_connect}:%{time_starttransfer}:%{time_total}

    -w一起使用的所有变量都可以在man curl中找到。


    选项1.测量total time

    1
    2
    curl -o /dev/null -s -w 'Total: %{time_total}s
    '  https://www.google.com

    样本输出:

    enter image description here

    选项2.获取time to establish connectionTTFB: time to first bytetotal time

    1
    2
    3
    4
    curl -o /dev/null -s -w 'Establish Connection: %{time_connect}s
    TTFB: %{time_starttransfer}s
    Total: %{time_total}s
    '  https://www.google.com

    样本输出:

    enter image description here

    参考:获得卷曲的响应时间


    您可以根据此处的其他答案添加到.bashrc等的快捷方式:

    1
    2
    3
    4
    function perf {
      curl -o /dev/null -s -w"%{time_connect} + %{time_starttransfer} = %{time_total}
    ""$1"
    }

    用法:

    1
    2
    > perf stackoverflow.com
    0.521 + 0.686 = 1.290


    以下是Simon的回答。它是独立的(不需要单独的格式文件),这使它非常适合包含在.bashrc中。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    curl_time() {
        curl -so /dev/null -w"\
       namelookup:  %{time_namelookup}s
    \
          connect:  %{time_connect}s
    \
       appconnect:  %{time_appconnect}s
    \
      pretransfer:  %{time_pretransfer}s
    \
         redirect:  %{time_redirect}s
    \
    starttransfer:  %{time_starttransfer}s
    \
    -------------------------
    \
            total:  %{time_total}s
    ""$@"
    }

    此外,它应该适用于curl通常采用的所有参数,因为"$@"只是通过它们。例如,你可以这样做:

    1
    curl_time -X POST -H"Content-Type: application/json" -d '{"key":"val"}' https://postman-echo.com/post

    输出:

    1
    2
    3
    4
    5
    6
    7
    8
       namelookup:  0,125000s
          connect:  0,250000s
       appconnect:  0,609000s
      pretransfer:  0,609000s
         redirect:  0,000000s
    starttransfer:  0,719000s
    -------------------------
            total:  0,719000s


    如果您想分析或总结延迟,可以尝试apache bench:

    1
    ab -n [number of samples] [url]

    例如:

    1
    ab -n 100 http://www.google.com/

    它将显示:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    This is ApacheBench, Version 2.3 <$Revision: 1757674 $>
    Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
    Licensed to The Apache Software Foundation, http://www.apache.org/

    Benchmarking www.google.com (be patient).....done


    Server Software:        gws
    Server Hostname:        www.google.com
    Server Port:            80

    Document Path:          /
    Document Length:        12419 bytes

    Concurrency Level:      1
    Time taken for tests:   10.700 seconds
    Complete requests:      100
    Failed requests:        97
       (Connect: 0, Receive: 0, Length: 97, Exceptions: 0)
    Total transferred:      1331107 bytes
    HTML transferred:       1268293 bytes
    Requests per second:    9.35 [#/sec] (mean)
    Time per request:       107.004 [ms] (mean)
    Time per request:       107.004 [ms] (mean, across all concurrent requests)
    Transfer rate:          121.48 [Kbytes/sec] received

    Connection Times (ms)
                  min  mean[+/-sd] median   max
    Connect:       20   22   0.8     22      26
    Processing:    59   85 108.7     68     911
    Waiting:       59   85 108.7     67     910
    Total:         80  107 108.8     90     932

    Percentage of the requests served within a certain time (ms)
      50%     90
      66%     91
      75%     93
      80%     95
      90%    105
      95%    111
      98%    773
      99%    932
     100%    932 (longest request)


    另一种方法是像这样配置~/.curlrc

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    -w"

    ==== cURL measurements stats ====
    total: %{time_total} seconds
    size: %{size_download} bytes
    dnslookup: %{time_namelookup} seconds
    connect: %{time_connect} seconds
    appconnect: %{time_appconnect} seconds
    redirect: %{time_redirect} seconds
    pretransfer: %{time_pretransfer} seconds
    starttransfer: %{time_starttransfer} seconds
    downloadspeed: %{speed_download} byte/sec
    uploadspeed: %{speed_upload} byte/sec

    "

    所以curl的输出是

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    ?? curl -I https://google.com
    HTTP/2 301
    location: https://www.google.com/
    content-type: text/html; charset=UTF-8
    date: Mon, 04 Mar 2019 08:02:43 GMT
    expires: Wed, 03 Apr 2019 08:02:43 GMT
    cache-control: public, max-age=2592000
    server: gws
    content-length: 220
    x-xss-protection: 1; mode=block
    x-frame-options: SAMEORIGIN
    alt-svc: quic=":443"; ma=2592000; v="44,43,39"



    ==== cURL measurements stats ====
    total: 0.211117 seconds
    size: 0 bytes
    dnslookup: 0.067179 seconds
    connect: 0.098817 seconds
    appconnect: 0.176232 seconds
    redirect: 0.000000 seconds
    pretransfer: 0.176438 seconds
    starttransfer: 0.209634 seconds
    downloadspeed: 0.000 byte/sec
    uploadspeed: 0.000 byte/sec


    嘿比Apache Bench更好,SSL问题更少

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    ./hey https://google.com -more
    Summary:
      Total:    3.0960 secs
      Slowest:  1.6052 secs
      Fastest:  0.4063 secs
      Average:  0.6773 secs
      Requests/sec: 64.5992

    Response time histogram:
      0.406 [1] |
      0.526 [142]   |????????????????????????????????????????
      0.646 [1] |
      0.766 [6] |??
      0.886 [0] |
      1.006 [0] |
      1.126 [0] |
      1.246 [12]    |???
      1.365 [32]    |?????????
      1.485 [5] |?
      1.605 [1] |

    Latency distribution:
      10% in 0.4265 secs
      25% in 0.4505 secs
      50% in 0.4838 secs
      75% in 1.2181 secs
      90% in 1.2869 secs
      95% in 1.3384 secs
      99% in 1.4085 secs

    Details (average, fastest, slowest):
      DNS+dialup:    0.1150 secs, 0.0000 secs, 0.4849 secs
      DNS-lookup:    0.0032 secs, 0.0000 secs, 0.0319 secs
      req write:     0.0001 secs, 0.0000 secs, 0.0007 secs
      resp wait:     0.2068 secs, 0.1690 secs, 0.4906 secs
      resp read:     0.0117 secs, 0.0011 secs, 0.2375 secs

    Status code distribution:
      [200] 200 responses


    另一个可能是命令行中最简单的选项是添加内置的--trace-time选项:

    1
    curl -X POST -d @file server:port --trace-time

    即使它在技术上不输出OP请求的各个步骤的时序,它也会显示请求的所有步骤的时间戳,如下所示。使用此功能,您可以(相当容易地)计算每个步骤的使用时间。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    $ curl https://www.google.com --trace-time -v -o /dev/null
    13:29:11.148734 * Rebuilt URL to: https://www.google.com/
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
      0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     013:29:11.149958 *   Trying 172.217.20.36...
    13:29:11.149993 * TCP_NODELAY set
    13:29:11.163177 * Connected to www.google.com (172.217.20.36) port 443 (#0)
    13:29:11.164768 * ALPN, offering h2
    13:29:11.164804 * ALPN, offering http/1.1
    13:29:11.164833 * successfully set certificate verify locations:
    13:29:11.164863 *   CAfile: none
      CApath: /etc/ssl/certs
    13:29:11.165046 } [5 bytes data]
    13:29:11.165099 * (304) (OUT), TLS handshake, Client hello (1):
    13:29:11.165128 } [512 bytes data]
    13:29:11.189518 * (304) (IN), TLS handshake, Server hello (2):
    13:29:11.189537 { [100 bytes data]
    13:29:11.189628 * TLSv1.2 (IN), TLS handshake, Certificate (11):
    13:29:11.189658 { [2104 bytes data]
    13:29:11.190243 * TLSv1.2 (IN), TLS handshake, Server key exchange (12):
    13:29:11.190277 { [115 bytes data]
    13:29:11.190507 * TLSv1.2 (IN), TLS handshake, Server finished (14):
    13:29:11.190539 { [4 bytes data]
    13:29:11.190770 * TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
    13:29:11.190797 } [37 bytes data]
    13:29:11.190890 * TLSv1.2 (OUT), TLS change cipher, Client hello (1):
    13:29:11.190915 } [1 bytes data]
    13:29:11.191023 * TLSv1.2 (OUT), TLS handshake, Finished (20):
    13:29:11.191053 } [16 bytes data]
    13:29:11.204324 * TLSv1.2 (IN), TLS handshake, Finished (20):
    13:29:11.204358 { [16 bytes data]
    13:29:11.204417 * SSL connection using TLSv1.2 / ECDHE-ECDSA-CHACHA20-POLY1305
    13:29:11.204451 * ALPN, server accepted to use h2
    13:29:11.204483 * Server certificate:
    13:29:11.204520 *  subject: C=US; ST=California; L=Mountain View; O=Google LLC; CN=www.google.com
    13:29:11.204555 *  start date: Oct  2 07:29:00 2018 GMT
    13:29:11.204585 *  expire date: Dec 25 07:29:00 2018 GMT
    13:29:11.204623 *  subjectAltName: host"www.google.com" matched cert's"www.google.com"
    13:29:11.204663 *  issuer: C=US; O=Google Trust Services; CN=Google Internet Authority G3
    13:29:11.204701 *  SSL certificate verify ok.
    13:29:11.204754 * Using HTTP2, server supports multi-use
    13:29:11.204795 * Connection state changed (HTTP/2 confirmed)
    13:29:11.204840 * Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
    13:29:11.204881 } [5 bytes data]
    13:29:11.204983 * Using Stream ID: 1 (easy handle 0x55846ef24520)
    13:29:11.205034 } [5 bytes data]
    13:29:11.205104 > GET / HTTP/2
    13:29:11.205104 > Host: www.google.com
    13:29:11.205104 > User-Agent: curl/7.61.0
    13:29:11.205104 > Accept: */*
    13:29:11.205104 >
    13:29:11.218116 { [5 bytes data]
    13:29:11.218173 * Connection state changed (MAX_CONCURRENT_STREAMS == 100)!
    13:29:11.218211 } [5 bytes data]
    13:29:11.251936 < HTTP/2 200
    13:29:11.251962 < date: Fri, 19 Oct 2018 10:29:11 GMT
    13:29:11.251998 < expires: -1
    13:29:11.252046 < cache-control: private, max-age=0
    13:29:11.252085 < content-type: text/html; charset=ISO-8859-1
    13:29:11.252119 < p3p: CP="This is not a P3P policy! See g.co/p3phelp for more info."
    13:29:11.252160 < server: gws
    13:29:11.252198 < x-xss-protection: 1; mode=block
    13:29:11.252228 < x-frame-options: SAMEORIGIN
    13:29:11.252262 < set-cookie: 1P_JAR=2018-10-19-10; expires=Sun, 18-Nov-2018 10:29:11 GMT; path=/; domain=.google.com
    13:29:11.252297 < set-cookie: NID=141=pzXxp1jrJmLwFVl9bLMPFdGCtG8ySQKxB2rlDWgerrKJeXxfdmB1HhJ1UXzX-OaFQcnR1A9LKYxi__PWMigjMBQHmI3xkU53LI_TsYRbkMNJNdxs-caQQ7fEcDGE694S; expires=Sat, 20-Apr-2019 10:29:11 GMT; path=/; domain=.google.com; HttpOnly
    13:29:11.252336 < alt-svc: quic=":443"; ma=2592000; v="44,43,39,35"
    13:29:11.252368 < accept-ranges: none
    13:29:11.252408 < vary: Accept-Encoding
    13:29:11.252438 <
    13:29:11.252473 { [5 bytes data]
    100 12215    0 12215    0     0   112k      0 --:--:-- --:--:-- --:--:--  112k
    13:29:11.255674 * Connection #0 to host www.google.com left intact


    我做了一个友好的格式化程序来嗅探curl请求以帮助调试(参见使用注释)。它包含您可以用易于阅读的格式写出的每个已知输出参数。

    https://gist.github.com/manifestinteractive/ce8dec10dcb4725b8513


    这是您可以与-w一起使用的字符串,包含curl -w支持的所有选项。

    1
    {"contentType":"%{content_type}","filenameEffective":"%{filename_effective}","ftpEntryPath":"%{ftp_entry_path}","httpCode":"%{http_code}","httpConnect":"%{http_connect}","httpVersion":"%{http_version}","localIp":"%{local_ip}","localPort":"%{local_port}","numConnects":"%{num_connects}","numRedirects":"%{num_redirects}","proxySslVerifyResult":"%{proxy_ssl_verify_result}","redirectUrl":"%{redirect_url}","remoteIp":"%{remote_ip}","remotePort":"%{remote_port}","scheme":"%{scheme}","size":{"download":"%{size_download}","header":"%{size_header}","request":"%{size_request}","upload":"%{size_upload}"},"speed":{"download":"%{speed_download}","upload":"%{speed_upload}"},"sslVerifyResult":"%{ssl_verify_result}","time":{"appconnect":"%{time_appconnect}","connect":"%{time_connect}","namelookup":"%{time_namelookup}","pretransfer":"%{time_pretransfer}","redirect":"%{time_redirect}","starttransfer":"%{time_starttransfer}","total":"%{time_total}"},"urlEffective":"%{url_effective}"}

    输出JSON。


    这是一个重复击中同一台服务器的Bash单行程序:

    1
    2
    for i in {1..1000}; do curl -s -o /dev/null -w"%{time_total}
    " http://server/get_things; done

    curl -v --trace-time
    这必须以详细模式完成