压测基础与工具选型
2.1 压测目标定义
在开始压测之前,必须明确压测的三个核心目标:
- 容量评估:确定系统在给定延迟预算(如 p99 < 100ms)下能承载的最大 QPS。
- 尾延迟验证:在持续负载下,验证 p99/p999 延迟是否满足 SLO(服务等级目标)。
- 瓶颈定位:通过逐步加压,发现 CPU、内存、GC、锁竞争等资源瓶颈点。
搜索系统压测的特殊性:搜索请求的查询复杂度差异极大(短词 vs 长句、缓存命中 vs 未命中),压测时必须使用真实查询日志分布,而非均匀随机字符串。
压测指标定义表:
| 指标 | 定义 | 搜索系统关注度 |
|---|---|---|
| QPS | 每秒查询数 | 高 |
| p50 延迟 | 50% 请求在多少毫秒内完成 | 中 |
| p99 延迟 | 99% 请求在多少毫秒内完成 | 极高 |
| p999 延迟 | 99.9% 请求在多少毫秒内完成 | 高 |
| 错误率 | 返回非 2xx/超时的请求占比 | 极高 |
| 吞吐量 | 单位时间内成功处理的请求总数 | 高 |
2.2 常用压测工具对比
业界主流的 HTTP 压测工具各有侧重,以下从Go 搜索系统压测的视角进行对比:
| 工具 | 语言 | 并发模型 | 延迟分布输出 | 自定义请求 | 分布式支持 | 适用场景 |
|---|---|---|---|---|---|---|
| wrk | C + Lua | 多线程 + epoll/kqueue | 仅 p50/p99/p999 | Lua 脚本 | 无 | 快速基准测试 |
| hey | Go | goroutine + 连接池 | 完整直方图 | 仅 URL/Header/Body | 无 | 简单 GET/POST 测试 |
| vegeta | Go | 固定速率 + goroutine | 完整直方图 + 百分位 | HTTP 文件模板 | 无 | 恒定速率压测 |
| k6 | Go (内核) + JS | 事件循环 + goroutine | 完整趋势图 + 阈值告警 | JavaScript 脚本 | 有 (k6-operator) | 复杂场景 + 持续集成 |
关键差异:wrk 性能最高但定制能力弱;hey 简单易用但无法控制请求速率;vegeta 速率控制精准但缺乏分布式能力;k6 功能最全但学习成本较高。
2.3 工具选型决策流程
选择压测工具应遵循以下决策逻辑:
- 是否需要恒定速率?是 → 选 vegeta 或 k6;否 → 选 wrk/hey。
- 是否需要复杂请求构造(如签名、动态参数)?是 → 选 k6 (JS) 或 wrk (Lua);否 → 选 hey/vegeta。
- 是否需要分布式压测?是 → 选 k6 (k6-operator);否 → 单机工具即可。
- 是否需要 CI/CD 集成?是 → 选 k6 (有官方 Docker + 阈值断言);否 → 选 vegeta。
避坑提示:不要用 wrk 做长时间尾延迟压测。wrk 的 Lua 脚本在长时间运行下容易出现内存泄漏,且其统计输出只包含三个百分位点,无法完整还原延迟分布曲线。
2.4 推荐方案:vegeta + k6 组合
针对 Go 搜索系统的尾延迟压测场景,推荐采用vegeta + k6 组合方案:
- 日常基准测试:使用 vegeta 进行恒定速率压测,输出完整延迟直方图,快速验证每次代码变更对尾延迟的影响。
- 复杂场景压测:使用 k6 编写 JavaScript 脚本,模拟不同查询类型(精确匹配、模糊搜索、聚合查询)的混合负载。
- CI/CD 集成:将 k6 测试用例集成到流水线中,设置 p99 延迟阈值(如 < 200ms),超过阈值则构建失败。
为什么不用 wrk? wrk 虽然性能极高,但其 Lua 脚本环境受限,无法方便地读取外部查询日志文件;且 wrk 的统计输出仅包含三个百分位点,对于尾延迟分析远远不够。vegeta 和 k6 都能输出完整的延迟分布数据,便于后续绘制延迟曲线图。
2.5 压测环境准备清单
在开始压测之前,请确认以下环境要素:
| 项目 | 要求 | 说明 |
|---|---|---|
| 压测机 | 独立机器,与目标服务同机房 | 避免网络延迟干扰测量结果 |
| 目标服务 | 开启详细延迟日志 | 用于与压测工具数据交叉验证 |
| 监控系统 | Prometheus + Grafana | 实时观察 CPU、内存、GC、goroutine 变化 |
| 查询日志 | 至少 10 万条真实查询 | 保证压测请求分布与线上一致 |
| 预热时间 | 至少 30 秒 | 让 JIT/缓存达到稳定状态后再记录数据 |
2.6 本章小结
- 压测目标必须围绕容量评估、尾延迟验证、瓶颈定位三个维度展开。
- wrk 适合快速基准测试,hey 适合简单场景,vegeta 适合恒定速率压测,k6 适合复杂场景和 CI/CD 集成。
- 针对 Go 搜索系统,推荐 vegeta(日常基准)+ k6(复杂场景 + CI) 的组合方案。
- 压测环境必须保证压测机与目标服务同机房,并使用真实查询日志分布。