Go语言全链路压测需从入口层捕获真实HTTP/gRPC流量再可控回放,因go test -bench仅单函数基准测试、不走网络栈、无法覆盖header透传、JWT签名、gRPC metadata、超时级联、熔断、连接池耗尽等关键链路行为。

Go 语言压测流量录制回放,不能靠 go test -bench 搞定,必须从入口层捕获真实 HTTP/gRPC 流量再可控回放。
为什么 go test -bench 不适合全链路压测
它只跑单函数,不走网络栈,压不出 header 透传、JWT 签名、gRPC metadata、超时级联这些关键链路行为。更测不出熔断触发、连接池耗尽、trace 丢帧等线上典型问题。你压出来的 QPS 和线上实际承载能力基本无关。
-
go test -bench的输入是硬编码的 mock 数据,不是真实请求体 - 无法还原网关 → A → B → C → DB 的调用时序和上下文传播
- 所有中间件逻辑(如鉴权、限流、日志埋点)在 bench 中被绕过
goreplay 录制:监听网卡,不改代码不加代理
它直接抓 input-raw 端口的原始 TCP 包,解析 HTTP 请求后保存为二进制格式(.gor 文件),对业务完全无侵入。
- 录制命令示例:
./gor -input-raw :8082 -output-file requests.gor - 生成的
requests_0.gor是可读文本(HTTP 方法、路径、header、body 都明文存着) - 别在生产环境直接回放——
goreplay自身会消耗 CPU 和连接资源,可能拖慢线上服务 - 注意端口权限:Linux 下监听
:80或:443需要root权限或cap_net_raw能力
goreplay 回放:控制速率、循环、并发,贴近真实压力
回放不是简单重发,关键在模拟真实节奏。靠参数组合实现“可控放大”:
Go 配置库,使用 spf13/viper — 分层优先级(flag > env >file > KV > default),提供 BindPFlag/BindPFlags、SetEnvPrefix + SetEnvKeyReplace 等功能。
立即学习“go语言免费学习笔记(深入)”;
- 基础回放:
./gor -input-file requests.gor -output-http "http://192.168.1.100:8082" - 10 倍速 + 50 并发:
--output-http-workers 50 --http-allow-method "GET|POST" - 无限循环回放(适合长时间稳压):
--input-file-loop - 过滤敏感接口:
--http-disallow-url "/admin/.*" --http-disallow-header "Authorization" - 回放超时设长一点,避免因下游延迟误判:
--output-http-timeout 30s
Sharingan 的 Go 原生集成:需要改代码,但支持 gRPC 和全链路上下文
如果你的服务是 Go 写的,且用了 gRPC 或依赖 OpenTracing/OpenTelemetry,Sharingan 比 goreplay 更合适——它在应用层埋点,能捕获 metadata、context deadline、span 信息。
- 必须用定制 Go 版本编译(如
go1.13),否则recorder/koala_grpc模块会报错 - 启动服务前要设环境变量:
export GOROOT=/tmp/recorder-go1.13 - 示例项目需加编译 tag:
go build -tags="replayer" -gcflags="all=-N -l" - 回放界面地址默认是
http://127.0.0.1:8998,但 session 列表里看不到 gRPC 请求体,得看日志或加 debug 输出
真正难的不是启动命令,而是让录制和回放两端的数据状态一致——DB 快照、缓存预热、第三方依赖 mock,这些不配平,回放结果就不可信。流量文件本身只是载体,环境一致性才是压测结论成立的前提。

















