作者:@ warrenchen
1. 什么是 pprof
- golang 自带的开箱即用的性能监控和分析工具。
- pprof 通过收集 profile.proto 格式的剖面数据集并生成文字以及图片报告用来帮助可视化和分析数据。
2. 三种使用方式
通过 http 获取采样数据文件
- 在 import 中引入。
go
1. _ "net/http/pprof"
- 在main()方法中添加下面。
go
1. go func() {
2. ip := "127.0.0.1:9999"
3. if err := http.ListenAndServe(ip, nil); err != nil {
4. fmt.Print("failed to start pprof on %s\n", ip)
5. }
6. }()
- 在浏览器输入http://localhost:9999/debug/pprof/即可看到如下页面:
Plain Text
1. allocs: 会采样自程序启动所有对象的内存分配信息(包括已经被GC回收的内存)
2. block: 阻塞信息,它所记录的是 goroutine 等待资源所花的时间
3. cmdline: 程序启动命令和参数
4. goroutine: 当前所有goroutine的堆栈信息
5. heap: 堆上活跃对象的内存信息,我们可以通过设置gc参数来实现在采样前运行gc
6. mutex: 锁竞争的采样信息
7. profile: cpu占用情况
8. threadcreate: 系统线程创建情况
9. trace: 当前程序运行的跟踪信息
通过 go test 采集数据
在代码中直接使用 runtime.StartCPUProfile/runtime.StopCPUProfile 采样信息
go
1. fCpu, _ := os.OpenFile("cpu.pprof", os.O_CREATE|os.O_RDWR, 0644)
2. defer fCpu.Close()
3. pprof.StartCPUProfile(fCpu)
4. defer pprof.StopCPUProfile()
5. fHeap, _ := os.OpenFile("heap.out", os.O_CREATE|os.O_RDWR, 0644)
6. defer fHeap.Close()
7. pprof.Lookup("heap").WriteTo(fHeap, 0)
可以得到两个文件 cpu.pprof, heap.out 在下面查看采样信息一节可以用文件替代http://127.0.0.1:9999/debug/pprof/
3. 接下来,是如何查看采样信息
命令行查看采样信息
go
1. go tool pprof `http://127.0.0.1:9999/debug/pprof/`
/pprof/后面可以是 allocs, block, goroutine, heap 等等。 以 heap 为例,通过以上命令得到下图:
- 接下来可以使用 top, web, list, traces 四个命令。
-
top: 与 linux 的 top 类似,主要有5个指标:
- a flat: 当前函数占用的内存。
- b flat%: 当前函数内存占使用中总内存的百分比。
- c sum%: 累积到当前函数总的 flat 百分比(包含当前函数)65.52% = 57.72%+7.79%,三个数字在下图中以红线标出。
- d cum: 累计量。指该函数加上该函数调用的函数总耗时。
- e cum%: cum 占 CPU 总时间的比例。
-
web: 会在浏览器展现各个函数之间的调用图,以及内存之间的关系,每个方框由两个标签组成:在 cpu profile 中,一个是方法运行的时间占比,一个是它在采样的堆栈中出现的时间占比(前者是 flat 时间,后者则是 cumulate 时间占比);框越大,代表耗时越多或是内存分配越多。
-
list:查看某个函数的代码以及每行代码的信息。
-
traces:查看调用栈。
通过浏览器打开可视化界面
go tool pprof -<http=:10000 http://127.0.0.1:9999/debug/pprof/heap>
- 在view中有 top, graph, peek, source, flame graph 等选项,top, graph 在命令行中已经讲过,peek 比 top 多了一些文件信息以及调用信息,source 和 list 类似,flame graph 则是火焰图,按照调用关系从上到下,火焰条的长度代表了该函数的占比
- sample 选项则是可以对采样对象进行筛选。
- a alloc_*: 系统分配过的资源。
- b inuse_*: 系统还没有释放的资源。
后续会找两个案例通过pprof来分析。
DevLake 连接 DevOps 数据孤岛的开源解决方案, 期待与您的交流!欢迎加入 Discord(英文) 或微信(中文)群组。
本文由博客一文多发平台 OpenWrite 发布!
{{o.name}}
{{m.name}}