延迟测量工具:一把尺子量到底
说实话,做延迟优化,最怕的是“我感觉”。
我感觉是网络慢,我感觉是数据库瓶颈,我感觉是代码写得烂——这些都是猜测。我个人的习惯是,不管遇到什么问题,先拿工具量一量。没有数据,就没有发言权。
这一章,我就带你过一遍我最常用的几个测量工具。它们就像手术刀,能帮你精准定位延迟到底卡在哪一环。
基础网络延迟测量:ping & curl
ping——最基础的探针
ping 测量的是网络层的往返时间。它发一个 ICMP 包,等对方回一个,就这么简单。
我在项目里遇到过好几次,业务方抱怨接口慢,结果一 ping,发现丢包率 30%,延迟飙到 500ms——这根本不是应用层的问题,是机房网络链路在抽风。直接找网络运维换路由,问题秒解。
# 连续 ping 100 次,统计延迟分布
ping -c 100 target.com
# 只看结果摘要
ping -c 100 -q target.com
curl——应用层延迟探测
ping 测的是网络层,但很多时候问题出在应用协议上。这时候我习惯用 curl。
curl 有几个参数特别好用:-w 可以输出自定义的时间指标。我经常用这个来快速判断“是网络慢还是服务端处理慢”。
# 输出 curl 各阶段耗时
curl -o /dev/null -s -w "\\nHTTP 状态码: %{http_code}\\n"
curl -o /dev/null -s -w "DNS 解析: %{time_namelookup}s\\n"
curl -o /dev/null -s -w "TCP 连接: %{time_connect}s\\n"
curl -o /dev/null -s -w "TLS 握手: %{time_appconnect}s\\n"
curl -o /dev/null -s -w "首字节: %{time_starttransfer}s\\n"
curl -o /dev/null -s -w "总耗时: %{time_total}s\\n"
curl -o /dev/null -s -w "下载速度: %{speed_download}B/s\\n" \
https://api.example.com/health
time_starttransfer 远大于 time_connect,说明服务端处理慢;如果 time_connect 本身很高,说明网络连接不稳定。
压测工具:wrk & ab
wrk——现代化的 HTTP 压测
wrk 是我目前最常用的压测工具。它基于 epoll/kqueue,能轻松打出几万并发。
说白了,它比 ab 更轻量,结果也更真实。我记得有一次做网关优化,用 wrk 压测才发现了连接池泄漏的问题——从第 5 秒开始,延迟曲线直接起飞。
# 基本用法:4 线程,100 连接,压 30 秒
wrk -t4 -c100 -d30s https://api.example.com
# 带自定义脚本压测 POST 接口
wrk -t4 -c200 -d60s -s post.lua https://api.example.com/submit
ab——经典的 Apache 压测
ab 是老牌工具了,胜在简单。虽然单机并发能力不如 wrk,但胜在随处可见。
我个人的习惯是:快速验证用 ab,长时间压测用 wrk。
# 100 个请求,并发 10
ab -n 100 -c 10 https://api.example.com/
# 带 Keep-Alive 压测
ab -k -n 1000 -c 50 https://api.example.com/
| 维度 | wrk | ab |
|---|---|---|
| 并发模型 | epoll/kqueue(事件驱动) | 多线程 + select |
| 单机并发上限 | 10 万+ 连接 | 几千连接 |
| 支持自定义脚本 | ✅ Lua 脚本 | ❌ 不支持 |
| 结果详细度 | 中等 | 较高(含时间分布) |
| 快速验证场景 | ✅ 推荐 | ✅ 可用 |
| 长时间压测 | ✅ 推荐 | ❌ 不推荐 |
系统级分析:perf & strace
perf——内核级采样器
perf 能深入到 CPU 指令级和内核栈。
嗯,这里要注意:perf 的数据量非常大。我一般先录 30 秒,然后看热点,而不是全量分析。
# 记录 30 秒 CPU 事件
perf record -g -F 99 -p PID -- sleep 30
# 生成火焰图数据
perf script > out.perf
# 用 FlameGraph 工具生成 SVG
stackcollapse-perf.pl out.perf | flamegraph.pl > flame.svg
为什么用 -F 99?因为 99Hz 采样率足够捕捉异常,又不会产生太多数据。我在定位一个 Redis 高延迟问题时,就是用 perf 发现 Redis 的内核态 spinlock 占了 40% 的 CPU——那是内核版本的一个 bug。
strace——系统调用侦探
strace 是跟踪进程和内核交互的利器。每次 read/write/connect 都能看到。
# 跟踪系统调用,统计耗时
strace -c -p PID
# 只看网络相关调用
strace -e network -T -p PID
# 跟踪子进程
strace -f -e trace=network -T -p PID
我曾经用 strace 抓到一个诡异问题:每次请求都会莫名其妙多等 300ms。结果发现是应用层在每次请求前做了一次 DNS 反向解析——上游 DNS 超时了。这种问题,不用 strace 根本就发现不了。
测量工具全景图
为什么需要这么多工具?因为它们分别覆盖了不同的层级。我画了一张图帮你梳理一下:
什么时候该用哪个?
我总结了几个典型的诊断场景,你可以照着来:
- 用户说“页面打不开”:先 ping,排除网络不通;再 curl -w,看哪一步卡住了。
- 接口响应忽快忽慢:上 wrk 压测,看 P99 延迟是否有抖动。如果有,说明服务端有资源争抢或 GC 问题。
- CPU 飙升但业务量不大:用 perf 采样,看热点在哪里。
- 某次请求特别慢:strace 抓一次完整请求的系统调用链。
避坑指南
还有一点:压测工具的结果不要只看平均值。平均值会骗人。你看 ab 的结果,它默认会给出“90% 的请求在多少 ms 内完成”——这个比平均值更有参考价值。