pprof
pprof是go语言自带的性能分析工具,在对go程序进行故障定位、性能调优时应用非常广泛。
pprof是一个分析工具,通过go tool pprof可以直接对采集样本进行分析。
什么情况下需要进行性能调优
一般常规内容:
- cpu:程序对cpu的使用情况 - 使用时长,占比等
- 内存:程序对cpu的使用情况 - 使用时长,占比,内存泄露等。如果在往里分,程序堆、栈使用情况
- I/O:IO的使用情况 - 哪个程序IO占用时间比较长
golang 程序中:
- goroutine:go的协程使用情况,调用链的情况
- goroutine leak:goroutine泄露检查
- go dead lock:死锁的检测分析
- data race detector:数据竞争分析,其实也与死锁分析有关
采样
样本的采集有三种方式:
- runtime/pprof 直接采样
一般用于工具型程序
package main
import (
"os"
"runtime/pprof"
)
func main() {
f, err := os.Create("./profile.out")
if err != nil {
os.Exit(1)
return
}
err = pprof.StartCPUProfile(f) //采集cpu profiling,程序退出就结束
if err != nil {
os.Exit(1)
return
}
defer pprof.StopCPUProfile()
// do something ...
hf, err := os.Create("./heap.out")
if err != nil {
os.Exit(1)
return
}
pprof.WriteHeapProfile(hf) //写入堆信息
}
采样文件会输出到./profile.out中。
- net/http/pprof 借助http服务采样
一般用于服务型程序
package main
import (
"net/http"
_ "net/http/pprof"
)
func main() {
http.ListenAndServe("localhost:8080",nil)
// do something
}
pprof在init时会向http.DefaultServerMux注册handler,如果使用自定义的多路复用器,只需要按照init方法,注册handler即可。
服务启动后,可以访问http://HOST:PORT/debug/pprof查看采样结果,
也可以使用curl将采样结果保存到本地文件,curl -sk -v http://HOST:PORT/debug/pprof/profile?secons=30s > profile.out
- Benchmark时采样
go test -cpuprofile cpu.prof -memprofile mem.prof -bench .
分析
分析采样数据有三种方式:
-
直接访问pprof的web网页,查看采样结果。
- Allocs: 查看过去所有内存分配样本
- Block:查看导致阻塞同步的堆栈跟踪
- cmdline:当前程序命令行
- goroutine:当前所有运行的goroutine堆栈跟踪
- heap:当前活动对象的内存分配情况
- mutex:争用互斥锁的竞争者的堆栈跟踪
- profile:默认进行30s的cpu profiling,生成profile文件
- threadcreate:导致创建新线程的堆栈跟踪
- trace
-
通过命令行交互方式查看
可以通过go tool pprof -h 查看可选参数
go tool pprof [source|binary] // go tool pprof cpuprofile.pprof // go tool pprof http://HOST:PORT/debug/pprof/heap // go tool pprof -svg http://HOST:PORT/debug/pprof/heap >heap.svg
进入交互命令后,可以使用命令进行查看分析:
- help可以查看帮助信息,o查看选项信息
- top、text对结果进行排序后展示
- flat表示当前函数占用的cpu时间
- flat%表示当前函数占cpu的占总用时间的百分比
- sum%表示flat%的累积值
- cum表示当前函数以及当前函数调用其他函数的时间,比如a调用b,那么a的cum的值就是包含b的调用时间,火焰图就是使用的cum
- cum%表示当前函数占总占用时间的百分比
- 通过top可以看出具体哪个函数比较耗时
- 使用list func1分析具体的函数,找到耗时的语句进行优化
- svg生成svg格式的输出
-
通过UI界面查看(推荐)
- 需要先安装graphviz软件,安装好将bin目录添加到环境变量,并使用dot -v验证是否装好。
- 执行
go tool pprof -http=:8888 heap.out
- 执行之后会在浏览器打开一个UI界面
UI界面包含三个栏目:
- VIEW 可以选择展示的形式,有top、graph、flamegraph等
- SAMPLE 选择展示的内容
- REFINE 配合Search regex对展示结果进行筛选
关于图形的一点说明:
- 每个框代表一个函数,理论上框越大表示占用的 cpu 资源越多
- 每个框之间的线条代表函数之间的调用关系,线条上的数字表示函数调用的次数
- 每个框中第一行数字表示当前函数占用 cpu 的百分比,第二行数字表示当前函数累计占用 cpu 的百分比
火焰图说明:
-
火焰图 svg 文件,你可以点击上面的每个方块来查看分析它上面的内容。
-
火焰图的调用顺序从下到上,每个方块代表一个函数,它上面一层表示这个函数会调用哪些函数,方块的大小代表了占用 CPU 使用时长长短。
参考
golang 性能优化分析工具 pprof (上) -来自九卷技术录,一个非常优质的博客
还有公众号网管叨bi叨的pprof系列