go pprof使用
pprof 简介
工欲善其事必先利其器, java 中有 async-profile、 arthas、jstack/jmap/jstat
等一系列工具来辅助排查性能问题
在 linux 下,常用的调试定位工具:
- vmstat、iostat、 mpstat、netstat、 sar 、top:查看系统、程序信息等
- gprof、perf、perf top:定位到具体函数、调用等
- strace、ltrace:系统调用、函数调用、库函数调用等
- pstack、ptree、pmap:堆栈信息
- dmesg:系统log信息
go 语言中在内存、性能排查方面主要使用 pprof
:
- pprof 是用于可视化和分析性能分析数据的工具
- pprof 以 profile.proto 读取分析样本的集合,并生成报告以可视化并帮助分析数据(支持文本和图形报告)
- profile.proto 是一个 Protocol Buffer v3 的描述文件,它描述了一组 callstack 和 symbolization 信息, 作用是表示统计分析的一组采样的调用栈,是很常见的 stacktrace 配置文件格式
pprof 的使用场景:
- CPU Profiling:CPU 分析,按照一定的频率采集所监听的应用程序 CPU(含寄存器)的使用情况,可确定应用程序在主动消耗 CPU 周期时花费时间的位置
- Memory Profiling:内存分析,在应用程序进行堆分配时记录堆栈跟踪,用于监视当前和历史内存使用情况,以及检查内存泄漏
- Block Profiling:阻塞分析,记录 goroutine 阻塞等待同步(包括定时器通道)的位置
- Mutex Profiling:互斥锁分析,报告互斥锁的竞争情况
pprof 的使用方式:
- Report generation:报告生成
- Interactive terminal use:交互式终端使用
- Web interface:Web 界面
pprof 使用
引入 pprof
pprof 是入侵式的, 需要先引入依赖:
1 |
|
然后显示的开启一个端口(最好是单独启一个协程, 如果程序是一个web服务, 避免和web Server公用同一个端口):
1 |
|
我们引入了两个包: net/http
和 net/http/pprof
, 前者是启动一个http服务监听一个端口, 后者做了几件事情:
- 在
init
里面注册路由:1
2
3
4
5
6
7func init() {
http.HandleFunc("/debug/pprof/", Index)
http.HandleFunc("/debug/pprof/cmdline", Cmdline)
http.HandleFunc("/debug/pprof/profile", Profile)
http.HandleFunc("/debug/pprof/symbol", Symbol)
http.HandleFunc("/debug/pprof/trace", Trace)
} - 实现
ServeHTTP
并注册以下几个路由:1
2
3
4
5
6
7
8var profileSupportsDelta = map[handler]bool{
"allocs": true,
"block": true,
"goroutine": true,
"heap": true,
"mutex": true,
"threadcreate": true,
}
通过 web 界面访问
直接访问ip:port/debug/pprof
可以看到一些子页面, 类似如下:
1 |
|
我们常用的一些性能分析数据可以从这些页面得到:
- cpu(CPU Profiling):
/debug/pprof/profile
,默认进行 30s 的 CPU Profiling,得到一个分析用的 profile 文件 - block(Block Profiling):
/debug/pprof/block
,查看导致阻塞同步的堆栈跟踪 - goroutine:
/debug/pprof/goroutine
,查看当前所有运行的 goroutines 堆栈跟踪 - heap(Memory Profiling):
/debug/pprof/heap
,查看活动对象的内存分配情况 - mutex(Mutex Profiling):
/debug/pprof/mutex
,查看导致互斥锁的竞争持有者的堆栈跟踪 - threadcreate:
/debug/pprof/threadcreate
,查看创建新 OS 线程的堆栈跟踪 - cmdline: 显示程序启动命令及参数
- trace: 程序运行跟踪信息
交互终端使用
- CPU Profile:
go tool pprof http://localhost:6060/debug/pprof/profile?seconds=60
执行该命令后,需等待 60 秒(可调整 seconds 的值),pprof 会进行 CPU Profiling。结束后将默认进入 pprof 的交互式命令模式,可以对分析的结果进行查看或导出。交互模式下具体的命令可以通过 help 查看命令说明
1 |
|
上面的示例在结束 CPU Profiling 后, 通过 top 命令查看CPU占用久的函数, top 输出各列的含义:
- flat:给定函数上运行耗时
- flat%:同上的 CPU 运行耗时总比例
- sum%:给定函数累积使用 CPU 总比例
- cum:当前函数加上它之上的调用运行总耗时
- cum%:同上的 CPU 运行耗时总比例
- 分析内存使用情况
go tool pprof http://localhost:6060/debug/pprof/heap
- 阻塞同步分析
go tool pprof http://localhost:6060/debug/pprof/block
- 锁竞争分析
go tool pprof http://localhost:6060/debug/pprof/mutex
- 协程堆栈分析
go tool pprof http://localhost:6060/debug/pprof/goroutine
可视化分析
pprof 还提供了可视化界面的查看, 有两种操作方式(需要提前安装 graphviz
支持):
- 在本机操作, 在交互式终端输入
web
, 此刻会打开浏览器跳转 - 如要将服务器/容器上的信息拉到本地分析, 在命令交互的时候会生成
.pb.gz
文件, 拉到本地后使用命令如:go tool pprof -http=:8081 ./pprof.pprof-amd64-linux.goroutine.001.pb.gz
即可跳转浏览器查看(有top占用、火焰图等信息)
备注: 这里生成的文件也可以采取 curl 生成:curl -o cpu.prof http://localhost:6060/debug/pprof/profile
go pprof使用
https://haobin.work/2023/06/25/go/go-pprof使用/