在测试http服务时,通常会使用curl想服务器发起http请求,curl会模拟浏览器的请求,也会帮助你与服务器建立tls/ssl连接。有时我们希望得到请求过程中的耗时,来优化客户端的体验,这时一般会用到curl的-w参数。
curl的统计指标
根据curl手册中的说明,curl允许我们在-w参数后指定一个文本,文本中可以包含%{MACRO}形式的参数,curl会将实际的请求耗时,替换到这些宏当中。
虽然也有一些文章描述该功能,但是对于耗时这块往往描述的不明确,甚至是错误的,为了验证耗时的真正含义,我使用-w参数加wireshark抓包验证了一下,整理了常见的耗时相关统计值和说明如下:
统计值 说明
time_namelookup 域名解析耗时
time_connect TCP连接耗时
time_appconnect TLS/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
1
2
3
4
5
6
7
由于没有指定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”
}
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
这次-w没有指定文件,而是直接将期望输出的变量写在-w参数中,因此不需要指定@符号。而jq命令用来格式化输出json,-o /dev/null是为了不让返回数据干扰json统计数据的输出。
————————————————
版权声明:本文为CSDN博主「一只coding猪」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_44446512/article/details/121376195