用 curl 拆解 HTTP 各阶段耗时
curl 的 -w 模板能把一次 HTTP 请求的耗时拆成若干阶段:DNS 解析、TCP 连接建立、TLS 握手、首字节到达以及整体耗时。用同一目标多次采样后对比各阶段,就能判断延迟主要发生在链路、握手还是服务端处理上,而不是笼统地说「接口慢」。
基本信息
| 命令形式 | curl -so /dev/null -w '<模板>' <URL> |
|---|---|
| 关键变量 | time_namelookup、time_connect、time_appconnect、time_starttransfer、time_total |
| 采样要求 | 多次重复取稳定区间,避开首次冷启动 |
| 解读方式 | 看各阶段之间的差值,而不是只看总时长 |
| 适用范围 | 所有支持 -w 的 curl 版本 |
典型使用场景
- 用户反馈接口变慢,先判断是网络还是服务端处理
- DNS 解析耗时异常时,确认是否与解析器有关
- TLS 握手成为主要耗时,评估会话复用与证书链问题
- 对比不同地域到同一服务的耗时差异
- 发布前后采集基线,量化变更对延迟的影响
计时模板
计时模板
curl -so /dev/null -w 'dns %{time_namelookup} conn %{time_connect} tls %{time_appconnect} ttfb %{time_starttransfer} total %{time_total}\n' https://example.com/healthz
# 重复 5 次取稳定值
for i in 1 2 3 4 5; do curl -so /dev/null -w '%{time_total}\n' https://example.com/healthz; done
curl -so /dev/null -w 'code %{http_code} size %{size_download}\n' https://example.com/healthz变量含义
| 变量 | 含义 | 判读要点 |
|---|---|---|
| time_namelookup | DNS 解析完成耗时 | 明显偏大说明解析环节有问题 |
| time_connect | TCP 连接建立耗时 | 减去解析时间即为连接耗时 |
| time_appconnect | TLS 握手完成耗时 | HTTPS 请求才有意义 |
| time_starttransfer | 首字节到达耗时 | 与服务端处理能力相关 |
| time_total | 整个请求的总耗时 | 与前面各项之差反映传输与收尾 |
判读方法
- 用相邻阶段相减得到每一段自己的耗时,不要直接比较绝对值
- 多次采样后看分布,单次结果容易受瞬时抖动影响
- 服务端处理时间用首字节时间减去连接与握手阶段估算
- 把结论与抓包、服务端日志对照,形成完整证据链
第一次请求往往包含 DNS 与连接的冷启动开销,直接拿来做基线会夸大延迟。至少重复几次,取稳定区间的数值。
若只测 /healthz 这类轻量探针,得到的主要是网络与握手耗时;要评估业务处理能力,应换成有真实逻辑的接口。