Hey与100万结果上限:超大规模压测时report如何截断统计数据
【免费下载链接】heyHTTP load generator, ApacheBench (ab) replacement项目地址: https://gitcode.com/GitHub_Trending/he/hey
hey是一个轻量级的 HTTP 压测工具(HTTP load generator),常被视为 ApacheBench(ab)的现代替代品。它支持按请求数、按并发、按 QPS 限速或按时长运行压测任务。当你把压测规模拉到千万级请求时,会遇到一个隐藏规则:hey 的 report 最多只记录 100 万个请求的详细数据,超出部分会被静默截断。本文带你快速搞懂这个 100 万上限在哪里生效、哪些统计受影响、哪些不受影响,以及超大规模压测该如何应对。
📌 上限在哪里定义:maxRes = 1000000
这个 100 万上限是一个写死的常量,位于报告模块中:
- 常量定义:requester/report.go 中声明
maxRes = 1000000,注释明确写着 "We report for max 1M results"(最多报告 100 万条结果)。 - 结果通道的容量也用了同样的 100 万上限:requester/requester.go 中
maxResult = 1000000,用于限制results通道的缓冲区大小。
初始化报告时,newReport 会用min(n, maxRes)决定各统计数组的预分配容量——也就是说,即使你声明了 5000 万请求,数组也最多按 100 万准备。
✂️ 核心机制:哪些数据被截断
统计的收口逻辑在 runReporter 中,它从结果通道持续消费每个请求的result。这里有一条关键分支:
if len(r.resLats) < maxRes { r.lats = append(r.lats, ...) // 其余各阶段耗时、状态码、offset 也一并追加 }翻译成大白话:
| 统计数据 | 超过 100 万后 | 原因 |
|---|---|---|
总请求数numRes | ✅ 完整累计 | 每条结果无条件自增 |
错误分布errorDist | ✅ 完整累计 | 错误不进入明细数组 |
| RPS(每秒请求数) | ✅ 准确 | 由numRes / 总时长计算,见 finalize |
| 响应时间直方图 | ⚠️ 只基于前 100 万条 | 由r.lats排序生成,见 histogram |
| 延迟分位数(10/25/50/75/90/95/99%) | ⚠️ 只基于前 100 万条 | 见 latencies |
| 最快 / 最慢 / 各阶段 Min-Max | ⚠️ 只基于前 100 万条 | 排序后取首尾值 |
| 状态码分布 | ⚠️ 只基于前 100 万条 | statusCodes数组同样被截断 |
| CSV 输出 | ⚠️ 最多 100 万行 | CSV 模板遍历的就是截断后的.Lats |
还有一个容易忽略的细节:平均值r.average = r.avgTotal / float64(len(r.lats))(见 report.go 第119行)。分子avgTotal累计了全部成功请求,分母却是截断后的数组长度。当请求数超过 100 万时,平均值会略微偏离真实值——这是"截断"最容易被误解的地方:RPS 是全量视角,分位数和直方图却是前 100 万条的视角。
🤔 为什么要设置 100 万上限
原因很直接:内存。每个成功请求都要在 7 个float64数组加 1 个int数组中各存一份明细(耗时、连接、DNS、写请求、首字节延迟、读响应、状态码、offset)。100 万条已需要数百 MB 量级的内存开销,若允许千万级请求全量入列,压测机本身可能先被内存拖垮。这个上限本质上是"用统计精度换内存安全"的工程折中。
🚀 超大规模压测的实用建议
- 优先按时间切片,而不是硬跑一千万。hey 的
-z时长模式(如-z 10m)下,内部请求数被设为MaxInt32(见 hey.go),最容易无意识突破 100 万。建议把长压测拆成多个 100 万以内的段落分别执行,最后合并各段报告。 - 看结果时先核对规模:如果本次请求数 > 100 万,请记住直方图、P99、最快/最慢这些数字只代表"前 100 万个成功请求",而 Requests/sec 和错误分布才是全量数据。
- 需要完整明细时用 CSV:加
-o csv可把逐请求指标导出为逗号分隔流(模板见 requester/print.go),便于后续在外部工具中做全量分析——同样受 100 万行上限约束,需配合切片策略。 - 关注错误不受影响:连接失败、超时等错误计数是全量累计的,判断"系统什么时候开始出错"依然可信。
✅ 快速自查清单
- 本次压测总请求数是否超过 1,000,000?
- 若是,是否已将分位数 / 直方图结论标注为"前 100 万条样本"?
- 是否用
-z跑长时长任务而未拆分? - 是否导出了 CSV 并确认行数未超上限?
一句话总结:hey 的 report 对"计数类"统计全量可信,对"明细类"统计最多保留前 100 万条。理解了 requester/report.go 中
maxRes这一处逻辑,你就能正确解读任何规模的压测报告。
更多参数说明可参考 README.md,项目入口逻辑在 hey.go,压测执行与并发调度见 requester/requester.go。
【免费下载链接】heyHTTP load generator, ApacheBench (ab) replacement项目地址: https://gitcode.com/GitHub_Trending/he/hey
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考