0.引言
因为之前负责的平台属于数据交易类系统,经常涉及与用户沟通网络传输耗时的问题,所以特此记录下curl指令的使用,方便后续同学参考
1.curl指令介绍
curl(Client URl)是一个用于传输数据的命令行工具,支持http、https、ftp、ftps、scp、sftp、telnet等多种协议,常用于API接口测试、网络连通性测试、文件上传下载等。
其基本语法格式为
curl [参数] [url]
其常用参数如下:
- 设置请求方式 -X
# GET请求
curl http://xxx.com/api
# POST请求
curl -X POST http://xxx.com/api
# PUT请求
curl -X PUT http://xxx.com/api
- 设置参数 -d
curl -X POST -d '{"key":"value"}' http://xxx.com/api
- 设置请求头 -H
curl -H "Authorization: Bearer xxx" -H "Content-Type: application/json" http://xxx.com/api
# POST请求设置Header
curl -X POST -H "Content-Type: application/json" -d '{"key":"value"}' http://xxx.com/api
- 下载文件 -o
curl -o file.txt http://xxx.com/file.txt
# 比如
curl -o README.md https://gitee.com/wuhanxue/wu_study/blob/master/README.md
- 上传文件 -F,–data-binary
# 表单文件上传
curl -F "file=@/path/to/file.jpg" http://xxx.com/upload
# 二进制上传
curl -X PUT --data-binary @file.jpg http://xxx.com/upload
- 调试模式 -v,-I
# 查询详细信息 -v
curl -v http://baidu.com
# 显示响应头 -I
curl -I http://baidu.com
- 使用FTP
# 下载 FTP 文件
curl -u username:password ftp://xxx.com/file.txt
# 上传文件到 FTP
curl -T localfile.txt -u username:password ftp://xxx.com/
- 耗时统计
curl -o /dev/null -s -w "\
DNS解析: %{time_namelookup}s\n\
TCP连接: %{time_connect}s\n\
SSL握手: %{time_appconnect}s\n\
首字节响应: %{time_starttransfer}s\n\
总耗时: %{time_total}s\n" \
https://xxx.com
2.测试接口网络耗时
有了上述指令用法的了解后,我们利用耗时统计参数,来对接口进行耗时测试,以方便我们了解各阶段耗时是否有异常,帮助进行优化
- 整体耗时测试
curl -o /dev/null -s -w "总耗时: %{time_total}秒\n" http://xxx.com/api
- 分阶段耗时统计
curl -o /dev/null -s -w "\
DNS解析耗时: %{time_namelookup}秒\n\
TCP连接耗时: %{time_connect}秒\n\
SSL握手耗时: %{time_appconnect}秒\n\
请求准备耗时: %{time_pretransfer}秒\n\
首字节等待耗时: %{time_starttransfer}秒\n\
总耗时: %{time_total}秒\n" \
https://example.com/api
其中这些时间参数的具体含义为:
time_namelookup:DNS 解析耗时
time_connect:TCP 连接建立耗时
time_appconnect:SSL/TLS 握手耗时(仅 HTTPS)
time_pretransfer:从请求开始到准备传输的耗时(包含 TCP + SSL 时间)
time_starttransfer:首字节等待耗时,从请求开始到服务器返回第一个字节的耗时(TTFB)
time_total:请求总耗时
- 测算平均耗时
需要注意的是,少数几次的耗时测试是不准确的,容易收到网络波动的影响,所以一般我们会多测试几次计算平均耗时,以下为调用10次的脚本
total=0
for i in {1..10}; do
time=$(curl -o /dev/null -s -w "%{time_total}" https://example.com/api)
total=$(echo "$total + $time" | bc)
echo "第 $i 次耗时: ${time}秒"
done
echo "平均耗时: $(echo "scale=3; $total / 10" | bc)秒"
3.各阶段耗时异常解决思路
如果出现这些各阶段耗时异常,我们如何定位问题点呢,这里给出几点建议:
- DNS解析耗时高 time_namelookup
检查DNS服务器以及本地DNS缓存配置或服务本身是否有异常
- TCP连接耗时高 time_connect
网络延迟或服务响应本身较慢,如果有异地多机房,可以选择就近机房访问,需要综合考虑地域距离问题,如果只有单机房,可以考虑拉专线,或者建立就近计算节点,以减少传输频率或数据量
- SSL握手耗时高 time_appconnect
这就需要优化TLS配置了,因为我还未遇到这块问题,暂时无实际处理经验来佐证理论知识,大家可参考网上其他文章说明
- 首字节等待耗时高 time_starttransfer
这一层实际上已经建立好网络连接了,问题在于后端服务器的性能了,需要实际去检查后端代码,查看接口调用链中哪一步有异常,可以通过打印日志再观察具体的代码耗时情况