2. 压测基础:压测工具选型、参数设置与结果解读

在定位尾延迟性能瓶颈之前,必须建立可靠的压测基础。本章从工具选型、参数配置、结果解读三个维度,帮助你在 Go 服务压测中获取有效数据,避免因压测方法不当导致误判。

2.1 压测工具选型

针对 Go 服务的尾延迟压测,主流工具有 wrk、vegeta、ghz。三者在协议支持、并发模型、延迟统计方面差异显著,选型需结合被测服务协议与压测目标。

特性 wrk vegeta ghz
协议支持 HTTP/1.1、HTTPS HTTP/1.1、HTTPS gRPC (HTTP/2)、Protobuf
并发模型 多线程 + epoll/kqueue 单进程 + goroutine goroutine + HTTP/2 流
延迟统计 平均值、标准差、百分位 平均值、百分位、直方图 平均值、百分位、延迟分布
脚本化 Lua 脚本(有限) 命令行 + JSON 配置 命令行 + 配置文件
适用场景 HTTP 短连接、高并发 HTTP 持续压测、CI/CD gRPC 服务、流式 RPC
选型建议: 如果被测服务是 gRPC 接口,优先使用 ghz;如果是 REST API,wrk 适合快速压测,vegeta 适合自动化压测与结果持久化。尾延迟分析需要精确的百分位数据,vegeta 和 ghz 的直方图输出更友好。

2.2 压测参数设置

压测参数直接影响尾延迟数据的真实性。核心参数包括 并发数、持续时间、请求速率。错误设置会导致压测结果偏离实际生产负载。

2.2.1 并发数

并发数指同时发送请求的虚拟用户数。对于 Go 服务,并发数应大于服务 goroutine 池大小,以暴露调度竞争和锁争用。建议从 10 开始,逐步递增至 500 或 1000,观察尾延迟拐点。

2.2.2 持续时间

持续时间必须覆盖服务的热身期和稳态期。Go 服务的 JIT 编译、内存分配器预热、连接池初始化通常需要 10–30 秒。建议压测时长 ≥ 60 秒,并丢弃前 10 秒数据。

2.2.3 请求速率

请求速率(RPS)控制压测强度。固定速率模式适合模拟稳定流量;递增速率模式适合寻找服务瓶颈。尾延迟压测推荐使用固定速率,避免速率波动引入噪声。

参数 推荐范围 尾延迟影响
并发数 10 – 1000 过高并发导致 goroutine 调度延迟
持续时间 60 – 300 秒 过短无法暴露慢请求累积效应
请求速率 100 – 10000 RPS 速率超过服务容量时尾延迟急剧上升
常见误区: 并发数不等于 RPS。并发数 × 单请求平均耗时 = 实际吞吐量。如果并发数设置过高但 RPS 未达到服务上限,压测结果会包含大量排队延迟,误导尾延迟分析。

2.3 压测结果解读

压测结果的核心指标包括 吞吐量、延迟百分位、错误率。尾延迟定位重点关注 P99、P99.9、P99.99 百分位。

2.3.1 吞吐量

吞吐量(RPS 或 TPS)反映服务处理能力。当吞吐量达到平台期后继续增加并发,尾延迟会显著上升,这是服务进入饱和区的标志。

2.3.2 延迟百分位

延迟百分位是尾延迟分析的核心。P50 代表中位数延迟,P99 代表 99% 请求的延迟上限,P99.9 和 P99.99 代表极端尾延迟。Go 服务的尾延迟通常由 GC 暂停、锁竞争、网络抖动引起。

2.3.3 错误率

错误率超过 1% 时,压测结果不可信。常见错误包括超时、连接重置、HTTP 5xx。错误请求的延迟数据通常被工具丢弃或标记,需单独分析。

尾延迟判读规则:
• P99 < 100ms:服务延迟健康
• P99 100–500ms:存在轻微尾延迟,需排查 GC 或锁
• P99 > 500ms 且 P99.9 急剧上升:服务进入饱和区或存在慢路径
• P99.99 比 P99 高 10 倍以上:存在极端尾延迟,需 pprof 定位
压测参数与尾延迟关系图 并发数 10 – 1000 持续时间 60 – 300 秒 请求速率 100 – 10000 RPS 压测负载 并发 × 速率 × 时长 压测结果指标 吞吐量 (RPS) | P50 / P99 / P99.9 / P99.99 延迟 | 错误率 尾延迟关注 P99.9 和 P99.99 的急剧上升 参数组合决定压测负载特征,尾延迟分析需结合 P99.9 和 P99.99 百分位

2.4 压测命令示例

以下给出 wrk、vegeta、ghz 的典型压测命令,参数设置遵循上述推荐值。

wrk 压测 HTTP 服务

wrk -t12 -c200 -d120s --latency http://localhost:8080/api/v1/hello

参数说明: -t12 表示 12 个线程,-c200 表示 200 个并发连接,-d120s 表示持续 120 秒,--latency 输出延迟百分位。

vegeta 压测 HTTP 服务

echo "GET http://localhost:8080/api/v1/hello" | vegeta attack \
  -rate=500 \
  -duration=120s \
  -workers=50 \
  | vegeta report --type=hist[0,50ms,100ms,200ms,500ms,1s]

参数说明: -rate=500 固定 500 RPS,-workers=50 并发工作协程数,--type=hist 输出自定义延迟直方图。

ghz 压测 gRPC 服务

ghz --insecure \
  --proto ./hello.proto \
  --call helloworld.Greeter.SayHello \
  -d '{"name":"test"}' \
  -c 100 \
  -n 50000 \
  --connections=10 \
  --timeout=5s \
  localhost:50051

参数说明: -c 100 并发数,-n 50000 总请求数,--connections=10 HTTP/2 连接数,--timeout=5s 单请求超时。

压测前检查清单:
• 确保被测服务已预热(至少 10 秒空跑)
• 关闭本地其他网络密集型进程
• 压测机与被测服务在同一内网,避免网络延迟干扰
• 记录压测机的 CPU、内存、网络使用率,排除压测机瓶颈

2.5 压测结果输出示例

以 wrk 的 --latency 输出为例,解读关键字段:

Latency Distribution (HdrHistogram - Recorded Latency)
 50.000%    2.34ms
 75.000%    3.12ms
 90.000%    4.56ms
 99.000%    8.90ms
 99.900%   15.20ms
 99.990%   28.50ms
 99.999%   45.10ms
100.000%   52.30ms

Detailed Percentile spectrum:
  Value   Percentile   TotalCount 1/(1-Percentile)
   2.340     0.500000       25000         2.00
   3.120     0.750000       37500         4.00
   4.560     0.900000       45000        10.00
   8.900     0.990000       49500       100.00
  15.200     0.999000       49950      1000.00
  28.500     0.999900       49995     10000.00
  45.100     0.999990       49999    100000.00
  52.300     1.000000       50000

解读要点:

  • P50 = 2.34ms,中位数延迟正常
  • P99 = 8.90ms,99% 请求在 9ms 内完成
  • P99.9 = 15.20ms,尾延迟开始显现
  • P99.99 = 28.50ms,极端尾延迟约为 P50 的 12 倍
  • P99.999 = 45.10ms,最大延迟 52.30ms,存在少量慢请求
尾延迟判定: 该示例中 P99.99 是 P99 的 3.2 倍,P99.999 是 P99 的 5.1 倍,说明存在明显的尾延迟分布。需要进一步使用 pprof 分析 P99.9 以上的慢请求调用栈。
压测结果解读流程 步骤1:检查错误率 错误率 < 1% 才可信 步骤2:查看吞吐量 是否达到平台期 步骤3:分析百分位 P99 / P99.9 / P99.99 P99.9 / P99 比值 > 3 倍? 是 → 存在尾延迟问题 否 → 服务健康 无需进一步分析 步骤4:pprof 定位瓶颈 CPU / heap / goroutine / mutex 压测结果解读应遵循错误率 → 吞吐量 → 百分位 → pprof 的递进流程

2.6 压测注意事项

  • 预热阶段: Go 服务的 GC 和内存分配器在启动后前 10 秒不稳定,压测数据应丢弃预热期。
  • 连接复用: HTTP/1.1 和 gRPC 的连接复用策略不同,压测时需设置合理的连接数,避免连接建立开销污染延迟数据。
  • 压测机资源: 压测机 CPU 使用率超过 80% 时,压测工具本身会成为瓶颈,需增加压测机或降低并发。
  • 数据持久化: 使用 vegeta 的 JSON 输出或 ghz 的 CSV 输出保存原始数据,便于后续对比分析。
尾延迟压测禁忌:
• 不要只压测 30 秒,尾延迟需要长时间暴露慢请求累积效应
• 不要忽略错误请求,错误请求的延迟数据可能被工具丢弃
• 不要只关注 P99,P99.9 和 P99.99 才是尾延迟的核心指标
• 不要在压测过程中调整服务配置,会导致数据不可比