用 curl --resolve 定点测试后端节点并拆分耗时
问题场景
排查接口变慢时,常见困惑是把 DNS 解析、TCP 建连、TLS 握手、后端首字节混在一起。DNS 慢会影响所有节点,后端节点慢往往只在某台机器出现。使用 curl --resolve 可让 URL 仍写成域名,但实际连接到指定 IP,从而在不改 hosts 文件的情况下定点测试某个后端节点。--resolve 的格式是 HOST:PORT:ADDRESS,它只影响 curl 自身,不改变系统 DNS。
最小可运行示例
使用文档保留域名 example.com 和 192.0.2.x 作为占位,替换为你的域名和节点 IP。脚本如下:
#!/usr/bin/env bash
set -euo pipefail
HOST='api.example.com'
PORT='443'
REQ_PATH='/health'
NODES=('192.0.2.10' '192.0.2.11')
FMT='ip=%{remote_ip} code=%{http_code} dns=%{time_namelookup} connect=%{time_connect} tls=%{time_appconnect} first=%{time_starttransfer} total=%{time_total}\n'
for ip in "${NODES[@]}"; do
echo "== $ip =="
curl --noproxy '*' -sS -o /dev/null --resolve "$HOST:$PORT:$ip" "https://$HOST:$PORT$REQ_PATH" -w "$FMT"
done
运行方法:保存为 probe.sh,执行 chmod +x probe.sh,再运行 ./probe.sh。输出每个节点一行,字段为秒。--noproxy '*' 避免代理干扰;-sS 静默但显示错误;-o /dev/null 丢弃响应体;-w 输出指标。remote_ip 用于确认连接到目标节点。
结果解读
curl 的计时变量是累计值:time_namelookup 从开始到名称解析完成;time_connect 到 TCP 建立;time_appconnect 到 TLS 握手完成,HTTP 下为 0;time_starttransfer 到收到首字节;time_total 总耗时。因此 HTTPS 下可以近似计算:
- DNS 耗时 ≈
time_namelookup - TCP 建连耗时 ≈
time_connect - time_namelookup - TLS 握手耗时 ≈
time_appconnect - time_connect - 首字节耗时 ≈
time_starttransfer - time_appconnect - 总耗时 =
time_total
HTTP 下没有 TLS,首字节耗时 ≈ time_starttransfer - time_connect。
关键点:使用 --resolve 时,DNS 由 curl 内置解析表提供,time_namelookup 往往很小,不能把它当作真实 DNS 解析耗时。判断 DNS 是否慢,需要做基线对照:同一 URL 不加 --resolve 运行一次,记录 time_namelookup 和 time_total;再加 --resolve 定点测试各节点。若不加 --resolve 时 DNS 阶段高、总耗时也高,而定点测试的 DNS 阶段低且总耗时明显下降,DNS 可能是瓶颈;若定点测试中 TCP、TLS 或首字节阶段仍高,则问题更可能在网络链路、握手配置或后端处理。单次结果受缓存、网络抖动影响,建议每个节点重复多次看分布,不要用一个样本下结论。
多节点对比步骤
- 准备节点 IP 列表,确保同一域名、端口、路径、请求方法一致。
- 先跑一次不带
--resolve的基线,记录time_namelookup、time_connect、time_appconnect、time_starttransfer、time_total。 - 对每个 IP 执行脚本,确认
remote_ip与目标 IP 一致。 - 每节点重复多次,按阶段差值整理成表,比较 TCP、TLS、首字节差异。
- 若某节点首字节高但 TCP/TLS 正常,优先查该节点应用处理、依赖或负载;若 TCP 高,查网络链路、防火墙、负载;若 TLS 高,查握手、证书链、会话复用策略;若基线 DNS 高而定点后整体下降,查 DNS 解析链路和缓存。
边界与限制
--resolve 只改 curl 的连接目标,不改 Host 头和 TLS SNI,证书仍按 URL 域名校验,因此适合有域名证书的 HTTPS 服务;节点证书与域名不匹配时会报错,测试环境可临时用 -k 绕过,但会失去证书验证信息,仅用于定位。若服务依赖代理、CDN、负载均衡或虚拟主机,直连节点可能得到不同行为;--noproxy '*' 可排除代理变量干扰,但生产环境需按实际网络配置调整。不要对敏感接口发送生产数据;示例路径 /health 应替换为允许探测的端点。重定向、HTTP/2、连接复用、TLS 会话恢复都会影响耗时,建议先测第一跳、每次新进程请求,必要时再单独分析。DNS 缓存也会影响基线,重复测试时需意识到结果可能变化。不要用 --resolve 绕过正常的访问控制或安全策略。
- 点赞
- 收藏
- 关注作者
评论(0)