背景
性能测试主要用于go benchmark等压力测试的场景下,进行cpu和内存的使用分析。这边主要使用pprof来进行性能的采集
性能查看
- topN
先使用命令进行cpu profiling分析
go tool pprof ./backend_server http://localhost:port/debug/pprof/profile
进入命令行后使用命令topN即可看到最耗时的N项调用
(pprof)top5
- 调用树
同上先进行cpu profiling分析, 再执行命令
(pprof)web
, 即可看到调用树
- 火焰图
- 使用go-torch将pprof生成的结果展示成火焰图的形式
brew install perl go get github.com/uber/go-torch git clone https://github.com/brendangregg/FlameGraph.git # 将FlameGraph代码加入环境变量下 export $PATH=$PATH:/path/to/FlameGraph # 运行生成svg格式火焰图 go-torch -u localhost:{pprof_port}
- 本地启用http端口读取pprof生成的profile文件,可以快捷获取go自带火焰图和调用树等信息
go tool pprof -http=:{web_port} pprof.samples.cpu.004.pb.gz
使用方式
程序应区分运行模式,默认TEST模式启用pprof,其他模式包括DEBUG模式不启用,以免造成性能损耗。
// 原生http
// 隐式导入pprof包, 即可进行性能采集检测
import _ "net/http/pprof"
func main() {
// 开启用于pprof的端口
http.ListenAndServe("localhost:10001", nil)
}
// gin
// 隐式导入pprof包
import _ "net/http/pprof"
import "github.com/gin-contrib/pprof"
func main() {
// ...
r := gin.New()
pprof.Register(r)
// ...
}
// grpc
// 隐式导入pprof包
import _ "net/http/pprof"
func main() {
// 在grpc监听的端口外额外监听一个http端口用于记录pprof结果
runtime.SetBlockProfileRate(1)
go func() {
http.ListenAndServe(":10001", nil)
}()
}
参数调试
例如像如下进行采样:
# cpu性能分析 (默认采样30秒 采样频率每秒100次)
go tool pprof http://localhost:10001/debug/pprof/profile
# 内存性能分析
go tool pprof http://localhost:10001/debug/pprof/heap
当程序的CPU使用率相对较低,或者程序中的操作非常快,这种低频的采样可能就无法获取到精准到信息,导致自己得到的性能分析图或者火焰图不准确。
这种情况下我们可以通过设置环境变量手动调整采样频率,提高采样的频数:
PPROF_SAMPLE_RATE=1000 go run main.go
参考
PREVIOUSk8s基础知识和名词整理
NEXTpostgres协议学习