应使用 httptest.NewRecorder 直接测试 Handler 性能,避免网络层干扰;真实链路压测用 go-wrk 或 hey,同时监控 goroutine、内存、GC 等关键指标。
用 net/http/httptest 测试 Handler 性能,不是测真实网络
很多人一上来就用 http.Get 去压测自己写的 API,结果测的其实是本地 DNS、TCP 握手、TLS 开销甚至本机网络栈——根本没打到业务逻辑上。真正想验证 Handler 本身的吞吐和延迟,得绕过网络层,直接调用。用 httptest.NewServer 或 httptest.NewRecorder 是更干净的方式。
-
httptest.NewRecorder()适合单次请求性能分析:构造*http.Request,传给你的http.HandlerFunc,用httptest.NewRecorder()捕获响应,再测执行耗时 -
httptest.NewServer()适合模拟客户端行为(比如带重试、并发请求),但底层仍是内存 HTTP server,不走 socket - 注意别在测试里混用真实外网地址(如
http://api.example.com),那会把 DNS 解析、连接池复用、超时策略全卷进来,干扰判断
用 go-wrk 或 hey 做真实链路压测
要测端到端表现(比如部署后的真实 QPS、P95 延迟、连接堆积),必须走真实 TCP 连接。Go 生态里 go-wrk 更轻量、可嵌入测试代码;hey 功能更全、输出更直观,两者都支持 HTTP/1.1 和 HTTP/2。
-
go-wrk -n 10000 -c 100 http://localhost:8080/api/users:发 1 万请求,100 并发,结果含平均延迟、各分位延迟、错误数 - 压测前确保服务已预热(先跑几百请求让 GC、JIT、连接池稳定),否则首秒数据偏差极大
- 注意
hey默认启用 keep-alive,而某些 client 库(如resty)默认关闭,行为不一致会导致连接数暴涨,触发too many open files - 如果服务启用了 HTTPS,记得加
-insecure参数跳过证书校验,否则hey会卡在 TLS handshake
监控关键指标:不只是 QPS 和延迟
QPS 高不代表健康。Golang 网络服务容易在几个隐蔽点崩:goroutine 泄漏、内存持续增长、GC 频繁停顿、HTTP 连接未及时关闭。光看响应时间会漏掉这些。