Go 原生 go test -bench 可测 API 吞吐量,需用 httptest.NewServer 模拟真实 HTTP 链路,自定义 http.Client 配连接池与 TLS 设置,复用 request,结合 pprof 定位瓶颈,并辅以 hey/vegeta 测分位延迟。
用 go test -bench 测 API 接口吞吐量
Go 原生测试框架就能跑基准,不需要额外装压测工具。关键不是写 handler,而是模拟 HTTP 请求链路——httptest.NewServer 启一个临时服务,再用 http.Client 打它。
- 必须用
httptest.NewServer而非直接调 handler 函数,否则绕过 net/http 栈,测的是纯逻辑,不是真实 API 延迟 - 在
BenchmarkXxx函数里循环调用client.Do(req),别用http.Get——它每次新建 client,开销大且无法复用连接 - 记得在 benchmark 结束前调
server.Close(),不然端口被占,连续跑会失败 - 加
req.Header.Set("Content-Type", "application/json")等头,否则某些中间件(如 gin 的 binding)可能误判请求格式
避免 net/http 默认 client 的坑
默认 http.DefaultClient 的 Transport 没配连接池,短连接 + 高并发下会大量 TIME_WAIT、DNS 重查、TLS 握手,结果完全失真。
- 自己 new 一个
http.Client,设置Transport.MaxIdleConns = 100、MaxIdleConnsPerHost = 100 - 加
Transport.IdleConnTimeout = 30 * time.Second,防连接空闲太久被服务端断开 - 如果测 HTTPS 接口,务必设
Transport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true},否则自签名证书或本地开发环境直接 panic - 别在 benchmark 循环里反复 new request,用
http.NewRequestWithContext复用*http.Request实例(需注意 body 不可重用,得用bytes.NewReader包裹)
用 pprof 定位真实瓶颈
benchmark 只告诉你 QPS 和 ns/op,但不知道慢在哪。直接集成 net/http/pprof,测完立刻抓 profile 数据。
- 在测试 server 启动后,注册 pprof:
server.Config.Handler = http.DefaultServeMux,再http.DefaultServeMux.Handle("/debug/pprof/", http.HandlerFunc(pprof.Index)) - 跑完 benchmark,用
wget http://localhost:PORT/debug/pprof/profile?seconds=30抓 30 秒 CPU profile -
go tool pprof cpu.pprof进交互模式,输入top10看耗时 top 函数;用web生成调用图(需 graphviz) - 特别注意
runtime.mallocgc占比高,说明频繁分配内存,可能是 JSON marshal/unmarshal 或中间件里没复用 buffer
真实场景要测「带负载的响应延迟分布」
go test -bench 给的是平均值,但线上用户卡顿往往来自 P95/P99 尾部延迟。这时候得换工具,比如 hey 或 vegeta。