Golang性能测试与压力测试有什么区别_测试目标差异说明

11次阅读

性能测试看函数级健康基线,压力测试看系统级崩溃临界点;前者用go test -bench测单函数响应与资源占用,后者用hey等工具模拟并发洪峰并监控服务端指标。

Golang性能测试与压力测试有什么区别_测试目标差异说明

性能测试看“能不能稳”,压力测试看“崩不崩得快”

性能测试:用 go test -bench 测单函数或接口的健康基线

它不是测系统扛不扛得住,而是问:这个函数在正常调用频次下,响应够不够快、内存占不占多、有没有隐性泄漏。典型场景是发版前验证一个新写的 CalculateTax() 函数是否比旧版慢 20%。

  • 必须用 BenchmarkXXX(b *testing.B) 函数,b.N 由 Go 自动调整,不是你硬写死的并发数
  • 别漏掉 b.ResetTimer() —— 初始化逻辑(如建连接、读配置)要放在这之前,否则会污染耗时统计
  • 生成的 -cpuprofile-memprofile 是给 pprof 分析用的,不是看数字大小,而是找火焰图里最宽的那条路径
  • 误区:拿 Benchmark 模拟 1000 并发请求 —— 它本质是串行循环调用,不反映 goroutine 调度、锁竞争、连接池争抢等真实服务瓶颈

压力测试:用外部工具模拟真实流量洪峰,目标是打穿系统

Go 自带的 testing 包不干这事;你要用 ghz(gRPC)、heyhttp)、vegeta 或自己写 goroutine + http.Client 控制并发。目标不是“跑完”,而是观察:CPU 到 95% 后响应时间怎么跳?redis 连接池满没满?下游服务是不是开始 503?

  • 关键参数不是“总请求数”,而是 -c(并发数)和 -z 30s(持续压测时长),例如:hey -c 200 -z 60s http://localhost:8080/api/order
  • 务必关掉客户端默认的 HTTP 连接复用(设 http.DefaultClient.Transport.MaxIdleConnsPerHost = 0),否则压不出连接池瓶颈
  • 服务端日志里如果大量出现 context deadline exceeded,别急着优化代码 —— 先查 netstat -an | grep :8080 | wc -l,可能是端口耗尽或 net.core.somaxconn 太小
  • 常见翻车点:本地压测机 CPU 先跑满,结果误判服务端不行;实际应监控服务端指标(toppidstat -u 1go tool pprof http://localhost:6060/debug/pprof/goroutine?debug=2

为什么不能只做一种?—— 因为瓶颈不在同一层

一个 BenchmarkDBQuery 跑出来 1.2ms,不代表线上 API 就能扛住 500 QPS:它没测数据库连接池排队、没测 jsON 序列化 GC、没测中间件限流熔断。反过来,压力测试发现超时了,但不知道是 ORM 层慢还是网络 dns 解析慢 —— 这时候就得靠 go test -benchmem -cpuprofile=prof.out 回到单点深挖。

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

  • 性能测试定位“谁慢”,压力测试暴露“哪崩”
  • 上线前必须过两关:Benchmark 达标(比如 P95 ≤ 50ms)+ 压力测试在 1.5 倍预期流量下不雪崩
  • 最容易被跳过的环节:压测后不做 pprof heap 对比 —— 很多内存泄漏只在长时高负载下才显现,Benchmark 看不出来

真正卡住人的从来不是“会不会压”,而是压完看到 200 个指标飘红时,不知道该盯 goroutines 数、http.Server.ReadTimeout,还是 database/sqlMaxOpenConns。先分清你在测“健康值”还是“临界点”,再选工具,少走一半弯路。

text=ZqhQzanResources