go test -bench 不用于真实压测,它仅测量单函数在理想内存环境下的纳秒级开销,不统计qps、p95延迟、错误率等生产指标;真压测应使用hey、vegeta或自写main程序控制并发、连接、超时与统计。

go test -bench 不是用来压测的,它测的是单函数在理想内存环境下的纳秒级开销,不是你关心的“QPS 多少”“P95 延迟多少”“并发 100 时会不会超时”。真要压 API,别碰 testing.B 当主入口。
为什么 BenchmarkHTTPGet(b *testing.B) 不等于压测 HTTP
常见错误现象:写了个 BenchmarkHTTPGet,跑出 120000 ns/op,换算成 8333 QPS,结果用 hey 一压只有 600 QPS,延迟还抖得厉害。
-
b.N是串行循环次数,不是并发数 —— 即使加了b.RunParallel,它也不统计失败、不管理超时、不复用连接池、不模拟真实 TCP 生命周期 - 默认禁用 GC、屏蔽调度抖动、绕过 net/http 底层 buffer 分配和 TLS handshake,测出来的是“裸调用”,不是“发请求”
- 所有耗时单位是
ns/op,无法映射到真实服务指标(如 requests/sec、p95 latency、error rate) - 没内置连接池控制,
http.Get每次都新建连接(除非你手动配&http.Client{Transport: ...}),而 benchmark 又不让你初始化 client 在循环外
testing.B 该用在哪儿才不白写
只适合纯内存、无副作用、零外部依赖的组件级比对场景。比如验证一个新写的哈希函数比 hash/fnv 快不快,或比较两种 slice 遍历方式的开销。
- 被测函数不能碰网络、磁盘、全局变量、
time.Now()、log.Print - 初始化数据(如构建大 map、预分配 slice)必须放在
b.ResetTimer()之前,否则计入耗时 - 想测并发安全?用
b.RunParallel,但它只负责分 goroutine 跑b.N次,不提供原子计数器或错误分类能力 - 加
-benchmem看allocs/op和B bytes/op,比单纯看 ns/op 更能暴露逃逸和冗余分配问题
真要压 HTTP 或 gRPC,绕开 go test 直接写 main
自己写压测逻辑比硬套 testing.B 更可控、更贴近生产行为。核心就四件事:控并发、管连接、设超时、分统计。
- 用
&http.Client{Timeout: 5 * time.Second, Transport: &http.Transport{MaxIdleConns: 200, MaxIdleConnsPerHost: 200}}避免连接风暴 - 每个请求必须包一层
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second),防止卡死 - 用
sync.WaitGroup+sync/atomic记录 success/fail/timeout 数,别用锁——高并发下争用严重 - 用
time.AfterFunc或time.Ticker控制持续时间,每秒打印当前 TPS 和 p95 延迟,方便管道进tsv或 gnuplot
ghz / hey / vegeta 这些工具比自己写更省事的地方
它们不是“替代方案”,而是针对真实链路设计的专用工具。你不用再纠结 transport 复用、goroutine 泄漏、直方图桶怎么分。
-
hey -c 50 -n 10000 http://localhost:8080/api直接输出 Requests/sec、P90/P99、失败率,本地调试够用 -
vegeta attack -targets=urls.txt -rate=200 -duration=60s | vegeta report -type=json输出含 status code 分布、延迟直方图、每秒请求数序列,CI 可直接解析 -
ghz --concurrency=100 --connections=10 --duration=30s才真正模拟多连接多 stream 的 gRPC 场景;光设--concurrency不设--connections,很可能被默认MaxConcurrentStreams=100卡住 - 所有工具默认走真实网络栈,会暴露 TLS 握手耗时、TCP 重传、服务端 accept 队列堆积等问题 —— 这些恰恰是
go test -bench故意绕开的
最容易被忽略的一点:压测机和被测服务别跑同一台机器。本地用 localhost 压,会跳过部分 TCP 栈和网卡中断,结果偏乐观;同时 CPU 和网络带宽争抢会让延迟毛刺变多,掩盖真实瓶颈。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











