Go 使用 pprof

Golang 可以使用 pprof 对代码进行性能监控,只需引用指定的包文件即可方便的调试,分别是:net/http/pprof 或者 runtime/pprof,而前者只是后者的封装,暴露出 http 接口

由于我主要写 web 程序,所以主要介绍 net/http/pprof

go tool pprof 其实只是复制了 google/pprof 的代码而已,封装成 go 工具而已,两者没有差别,而且 google/pprof 的 web 界面更加好看,更新更加及时,所以我主要使用 google/pprof 进行调试。

推荐使用 pprof –help 查看更多帮助信息

准备工作

pprof 生成图片需要安装 Graphviz,在 Ubuntu 下直接使用命令即可

$ sudo apt install graphviz

go tool pprof 是自带的,但是如果想用 google/pprof 则需要下载安装,输入下面的命令即可

$ go get -u github.com/google/pprof

而且最新版的 google/pprof 和 go tool pprof 都已经支持火焰图,所以不用使用 go-torch

在程序中使用 pprof

使用 pprof 程序需要引入指定的包,对于 net/http 编写的 web 程序来说,只需要引用包文件即可

import _ "net/http/pprof"

如果使用了其他 web 框架则需要指定一下路由

r.HandleFunc("/debug/pprof/", pprof.Index)
r.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
r.HandleFunc("/debug/pprof/profile", pprof.Profile)
r.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
r.HandleFunc("/debug/pprof/trace", pprof.Trace)

对于 Gin 框架除了手动添加地址还可以使用封装好的 DeanThompson/ginpprof

不管使用了哪种方法,最后都可以通过 /debug/pprof/ 路由访问到以下界面

/debug/pprof/

Types of profiles available:
Count   Profile
0   allocs
0   block
0   cmdline
3   goroutine
0   heap
0   mutex
0   profile
7   threadcreate
0   trace
full goroutine stack dump 
Profile Descriptions:

allocs: A sampling of all past memory allocations
block: Stack traces that led to blocking on synchronization primitives
cmdline: The command line invocation of the current program
goroutine: Stack traces of all current goroutines
heap: A sampling of memory allocations of live objects. You can specify the gc GET parameter to run GC before taking the heap sample.
mutex: Stack traces of holders of contended mutexes
profile: CPU profile. You can specify the duration in the seconds GET parameter. After you get the profile file, use the go tool pprof command to investigate the profile.
threadcreate: Stack traces that led to the creation of new OS threads
trace: A trace of execution of the current program. You can specify the duration in the seconds GET parameter. After you get the trace file, use the go tool trace command to investigate the trace.

页面都说明了各个子页面的作用,其中几个主要的子页面是:

  • /debug/pprof/profile:访问这个链接会自动进行 CPU profiling,持续 30s,并生成一个文件供下载
  • /debug/pprof/heap: Memory Profiling 的路径,访问这个链接会得到一个内存 Profiling 结果的文件
  • /debug/pprof/block:block Profiling 的路径
  • /debug/pprof/goroutines:运行的 goroutines 列表,以及调用关系

如果程序不是 web 程序,则可以使用 runtime/pprof 或者在程序中开启一个 httpserver

import _ "net/http/pprof"

go func() {
    log.Println(http.ListenAndServe("localhost:6060", nil))
}()

通过 pprof 查看性能数据

使用pprof工具查看 heap:

$ go tool pprof http://localhost:6060/debug/pprof/heap

查看周期30秒的CPU剖面,如果不指定 second 则默认为 30s:

$ go tool pprof http://localhost:6060/debug/pprof/profile?seconds=30

查看go程阻塞剖面:

$ go tool pprof http://localhost:6060/debug/pprof/block

其实推荐 pprof 自带的 web 方式,就是在刚刚的命令前面加 -http 127.0.0.1:6060 或者 -http :6060

$ go tool pprof -http=[host]:[port] [options] source

对于内存性能监控 可以使用 alloc_space 查看共分配内存,inuse_space 查看常驻内存(正在使用中),具体操作如下图所示。然后输入 web 命令则可以用浏览器打开生成的图片,或者输入 topN 查看排行榜

pprof web 界面:

pprof 自带火焰图:

pprof 工具特别强大,除了支持 URL 调用,还支持使用下载下载的文件进行分析,例如可以用浏览器打开 http://127.0.0.1:8080/debug/pprof/heap ,然后

$ go tool pprof http://localhost:6060/debug/pprof/heap

如果应用比较复杂,生成的调用图特别大,看起来很乱,有两个办法可以优化:

使用 web funcName 的方式,只打印和某个函数相关的内容 运行 go tool pprof 命令时加上 –nodefration=0.05 参数,表示如果调用的子函数使用的 CPU、memory 不超过 5%,就忽略它,不要显示在图片中

go tool trace

go tool trace 也是特别强大的工具,下载 http://localhost:6060/debug/pprof/trace,然后调用工具进行分析

$ go tool trace ~/download/trace

压力测试工具

Web Bench

Web Bench 官网

安装,需要先安装 ctags

$ sudo apt install ctags
$ wget http://home.tiscali.cz/~cz210552/distfiles/webbench-1.5.tar.gz
$ tar zxvf webbench-1.5.tar.gz
$ cd webbench-1.5
$ make
$ make install
# webbench -c 并发数 -t 运行测试时间 URL
$ webbench -c 100 -t 10 http://127.0.0.1:8080/

URL 最后需要跟上 /

go-wrk

go-wrk


pprof 其实有很多待学习的地方,这篇只是记录常用使用方法,还有更强大的功能需要学习

要善用命令的 help 功能

参考链接