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

性能测试看“能不能稳”,压力测试看“崩不崩得快”
性能测试:用 go test -bench 测单函数或接口的健康基线
它不是测系统扛不扛得住,而是问:这个函数在正常调用频次下,响应够不够快、内存占不占多、有没有隐性泄漏。典型场景是发版前验证一个新写的 CalculateTax() 函数是否比旧版慢 20%。
- 必须用
BenchmarkXXX(b *testing.B)函数,b.N由 Go 自动调整,不是你硬写死的并发数 - 别漏掉
b.ResetTimer()—— 初始化逻辑(如建连接、读配置)要放在这之前,否则会污染耗时统计 - 生成的
-cpuprofile或-memprofile是给pprof分析用的,不是看数字大小,而是找火焰图里最宽的那条路径 - 误区:拿
Benchmark模拟 1000 并发请求 —— 它本质是串行循环调用,不反映 goroutine 调度、锁竞争、连接池争抢等真实服务瓶颈
压力测试:用外部工具模拟真实流量洪峰,目标是打穿系统
Go 自带的 testing 包不干这事;你要用 ghz(gRPC)、hey(HTTP)、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 先跑满,结果误判服务端不行;实际应监控服务端指标(
top、pidstat -u 1、go 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/sql 的 MaxOpenConns。先分清你在测“健康值”还是“临界点”,再选工具,少走一半弯路。











