curl获取请求时间统计

在测试http服务时,通常会使用curl想服务器发起http请求,curl会模拟浏览器的请求,也会帮助你与服务器建立tls/ssl连接。有时我们希望得到请求过程中的耗时,来优化客户端的体验,这时一般会用到curl的-w参数。

curl的统计指标

根据curl手册中的说明,curl允许我们在-w参数后指定一个文本,文本中可以包含%{MACRO}形式的参数,curl会将实际的请求耗时,替换到这些宏当中。

虽然也有一些文章描述该功能,但是对于耗时这块往往描述的不明确,甚至是错误的,为了验证耗时的真正含义,我使用-w参数加wireshark抓包验证了一下,整理了常见的耗时相关统计值和说明如下:

统计值说明
time_namelookup域名解析耗时
time_connectTCP连接耗时
time_appconnectTLS/SSL连接耗时
time_pretransfer发送预处理耗时
time_starttransfer数据传输及服务端处理耗时
time_redirect重定向耗时
time_total总体耗时

每一个参数都包含前面所有参数的耗时,这样说不太容易理解,上图比较好说明:



所以time_connect的含义是TCP建立连接时间,而实际上,它包含了域名解析的时间,所以如果仅希望获得TCP的三次握手耗时,应当用time_connect - time_namelookup,后面的参数也是一样。如果希望获得数据往返传输和服务器处理的耗时,就需要用time_starttransfer - time_pretransfer。

实践

来看下实际的示例,首先来写一个包含参数的文本文件

\n
time_namelookup: %{time_namelookup}\n
time_connect: %{time_connect}\n
time_appconnect: %{time_appconnect}\n
time_pretransfer: %{time_pretransfer}\n
time_redirect: %{time_redirect}\n
time_starttransfer: %{time_starttransfer}\n
\n

将文件保存为curl.txt,使用curl模拟请求www.baidu.com,-w参数指定该文本文件

$ curl http://www.baidu.com/ -w '@curl.txt'
            time_namelookup:  0.010484
               time_connect:  0.023659
            time_appconnect:  0.000000
           time_pretransfer:  0.023833
              time_redirect:  0.000000
         time_starttransfer:  0.039934

由于没有指定https协议,所以time_appconnect这块的时间为0。而TCP建立连接的时间=0.023659 - 0.010484 = 0.013175秒,同理,网络传输和服务器处理耗时为0.016101秒。
这些时间有助于发现客户端体验方面的性能问题,进一步进行优化。

更丰富的参数

当然curl的-w除了性能参数,还支持很多其他参数,如果你图省事,也可以直接用%{json}这个参数,他会以json形式将-w参数支持的所有值都输出出来

$ curl -s http://www.baidu.com/ -w '%{json}' -o /dev/null | jq
{
  "content_type": "text/html",
  "errormsg": null,
  "exitcode": 0,
  "filename_effective": "/dev/null",
  "ftp_entry_path": null,
  "http_code": 200,
  "http_connect": 0,
  "http_version": "1.1",
  "local_ip": "172.16.120.205",
  "local_port": 59399,
  "method": "GET",
  "num_connects": 1,
  "num_headers": 11,
  "num_redirects": 0,
  "proxy_ssl_verify_result": 0,
  "redirect_url": null,
  "referer": null,
  "remote_ip": "180.101.49.11",
  "remote_port": 80,
  "response_code": 200,
  "scheme": "HTTP",
  "size_download": 2381,
  "size_header": 400,
  "size_request": 77,
  "size_upload": 0,
  "speed_download": 52439,
  "speed_upload": 0,
  "ssl_verify_result": 0,
  "time_appconnect": 0,
  "time_connect": 0.026548,
  "time_namelookup": 0.011452,
  "time_pretransfer": 0.026612,
  "time_redirect": 0,
  "time_starttransfer": 0.045227,
  "time_total": 0.045405,
  "url": "http://www.baidu.com/",
  "url_effective": "http://www.baidu.com/",
  "urlnum": 0,
  "curl_version": "libcurl/7.79.1 (SecureTransport) OpenSSL/1.1.1l zlib/1.2.11 brotli/1.0.9 zstd/1.5.0 libidn2/2.3.2 libssh2/1.10.0 nghttp2/1.46.0 librtmp/2.3 OpenLDAP/2.5.7"
}

这次-w没有指定文件,而是直接将期望输出的变量写在-w参数中,因此不需要指定@符号。而jq命令用来格式化输出json,-o /dev/null是为了不让返回数据干扰json统计数据的输出。

posted @   一只coding猪  阅读(192)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
点击右上角即可分享
微信分享提示