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。
立即学习“go语言免费学习笔记(深入)”;
-
hey -n 10000 -c 100 -m POST -H "Content-Type: application/json" -d '{"id":1}' http://localhost:8080/api/user—— 100 并发打 1 万次 - 关注输出里的
Latency distribution,尤其是 90%、95%、99% 分位延迟,不是平均值 - 如果 P99 突然跳高,大概率是 GC STW、锁竞争(比如全局 map 未加锁)、或 DB 连接池耗尽;这时回过头看 pprof 的 mutex profile
- 别只测单 endpoint,组合路径(如登录 → 获取列表 → 提交)更能暴露上下文传递、中间件累积开销问题
实际调优时,最常被忽略的是中间件顺序和 context 传递成本:一个带 5 层中间件的 gin handler,即使每层只做 log.Println,P99 延迟也可能多出 2ms——这在高频接口里就是瓶颈。











