Golang Web如何进行压力测试_Golang Web性能压测

2次阅读

go test -bench 不是 web 压测工具,仅测 handler 内存与 cpu 逻辑;真实压测需走网络、控并发、收 qps 与延迟分布,应使用 hey 或 vegeta 等外部工具。

Golang Web如何进行压力测试_Golang Web性能压测

Go 的 go test -bench 不是 Web 压力测试工具,它测的是 handler 内存+CPU 逻辑,不是真实 http 服务吞吐。真要压 Web 服务,得走网络栈、控并发、收 QPS 和延迟分布——这三件事 testing.B 根本不干。

httptest 做 Benchmark 只适合验证 handler 逻辑

它把请求和响应塞进内存里跑,跳过 TCP、TLS、连接池、反向代理、路由分发这些真实瓶颈点。适合的场景很窄:

  • 确认某个 http.HandlerFunc 里没写死循环、没意外分配大对象
  • 对比两种 json 解析方式(json.Unmarshal vs easyjson)在纯内存下的开销
  • 排查中间件是否引入锁竞争(需配合 -cpuprofile

实操时务必:b.ResetTimer() 放在初始化之后;log.SetOutput(io.Discard) 关掉日志;别在循环里 time.Sleep 或新建 *http.Client。否则数据全失真。

真实链路压测必须用外部工具:推荐 heyvegeta

hey 轻量、输出干净、默认禁用 keep-alive,适合快速摸底;vegeta 支持 POST/JSON/header/阶梯加压,适合 API 链路。两者都比手写 goroutine 更稳——你不用操心连接复用、超时穿透、goroutine 泄漏。

立即学习go语言免费学习笔记(深入)”;

  • hey -c 100 -z 30s -H "Connection: close" http://localhost:8080/api 模拟 100 并发持续 30 秒,强制关闭连接
  • echo "GET http://localhost:8080/api" | vegeta attack -rate=200 -duration=30s -timeout=5s | vegeta report 控制精确 RPS
  • 所有命令里必须加 -timeout 和显式关 keep-alive,否则客户端复用会掩盖服务端 accept 队列或连接池瓶颈

自己写压测脚本?关键不是发请求,而是控节奏和防泄漏

新手常犯错误:for i := 0; i —— 这瞬间起 1000 协程,打爆本地文件描述符或目标服务。真正要控制的是并发数、请求间隔、错误重试和结果聚合。

  • 用带缓冲 channelsemaphore 限制最大并发,比如 sem := make(chan Struct{}, 50)
  • 每个请求用独立 *http.Request,设 req.Close = true 避免复用干扰单次计时
  • sync.WaitGroup 等全部完成,用 time.Now() 记每请求耗时,最后算 P95/P99,别只看平均值
  • 压测机和服务端必须分离,同一台机器压自己,CPU 和网卡争抢会让结果毫无参考价值

压测最易被忽略的一点:每次运行前清缓存、重启服务、调 debug.FreeOSMemory()、关日志。不这么做,三次压测结果波动可能比优化带来的提升还大。

text=ZqhQzanResources