1 pprof简介
golang代码的性能监控使用pprof包来做。pprof有两个包:
-
runtime/pprof
pprof的具体实现,所有类型的代码都可以使用。如果不是Web应用程序,建议使用该包。 -
net/http/pprof
对runtime/pprof
包进行简单封装,并在http端口上暴露出来。适合Web应用程序使用。
2 pprof监控内容
pprof监控的内容项目入下表所示。
类型 | 描述 | 备注 |
---|---|---|
allocs | 内存分配情况的采样信息 | 可以用浏览器打开,但可读性不高 |
blocks | 阻塞操作情况的采样信息 | 可以用浏览器打开,但可读性不高 |
cmdline | 显示程序启动命令及参数 | 可以用浏览器打开,但可读性不高 |
goroutine | 当前所有协程的堆栈信息 | 可以用浏览器打开,但可读性不高 |
heap | 堆上内存使用情况的采样信息 | 可以用浏览器打开,但可读性不高 |
mutex | 锁争用情况的采样信息 | 可以用浏览器打开,但可读性不高 |
profile | CPU 占用情况的采样信息 | 浏览器打开会下载文件 |
threadcreate | 系统线程创建情况的采样信息 | 可以用浏览器打开,但可读性不高 |
trace | 程序运行跟踪信息 | 浏览器打开会下载文件 |
3 使用pprof进行监控
一下两种使用pprof进行性能监控的方式只能生成监控信息文件,具体的分析需要使用go tool pprof [binary] file
进行查看和分析。
3.1 非Web应用程序
非Web应用程序使用包runtime/pprof
,生成监控文件。
下面示例进行CPU监控,并将监控数据存放在当前项目的pprof/profile_file/profile_file文件中。
import (
"log"
"os"
"path/filepath"
"runtime/pprof"
)
// 进行CPU监控
func CreateProfileFile() {
dir, err := os.Getwd()
if err != nil {
log.Fatalln("get current directory failed.", err)
}
fileName := filepath.Join(dir, "pprof", "profile_file", "profile_file")
f, _ := os.Create(fileName)
// start to record CPU profile and write to file `f`
_ = pprof.StartCPUProfile(f)
// stop to record CPU profile
defer pprof.StopCPUProfile()
// TODO do something
}
3.2 Web应用程序
Web应用程序使用包net/http/pprof
,可以搭建Web服务器查看监控信息。通过http://locahost:6060/debug/pprof进行查看相关的监控信息文件。
import (
"log"
"net/http"
_ "net/http/pprof"
"os"
"runtime"
)
func main() {
log.SetFlags(log.Lshortfile | log.LstdFlags)
log.SetOutput(os.Stdout)
runtime.GOMAXPROCS(1)
runtime.SetMutexProfileFraction(1)
runtime.SetBlockProfileRate(1)
go func() {
if err := http.ListenAndServe(":6060", nil); err != nil {
log.Fatal(err)
}
os.Exit(0)
}()
注意
如果你使用自定义的 Mux,则需要手动注册一些路由规则:
mux.HandleFunc("/debug/pprof/", pprof.Index)
mux.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
mux.HandleFunc("/debug/pprof/profile", pprof.Profile)
mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
mux.HandleFunc("/debug/pprof/trace", pprof.Trace)
4 pprof监控信息使用
golang原生自带pprof工具的go tool pprof [binary] file
命令进入交互式终端来排查应用程序的性能问题。其中,
-
binary
正在执行的二进制可执行程序,可选。 -
file
pprof监控生成的文件。可以是具体的文件如profile.pprof,也可以是web站点的地址,如http://localhost:6060/debug/pprof/profile。
进入终端之后,排查性能问题的三个命令为: -
top
查看资源较高的调用。 -
list
list 代码片段
查看问题代码具体位置。 -
web
在Web Browser上图形化显示当前的资源监控内容。需要事先安装graphviz。
web
命令的实际行为是产生一个.svg
文件,并调用系统里设置的默认打开.svg
的程序打开它。如果系统里打开.svg
的默认程序并不是浏览器(比如代码编辑器),需要设置一下默认使用浏览器打开.svg
文件。然后浏览器自动打开,可以看到:
如果需要其他命令,可以在pprof交互式终端里输入help
查看其他命令的使用方法。例如,
-
svg
生成svg图。 -
pdf
生成pdf文件,显示svg图。 -
png
生成png图片,显示svg图。 - ...
当然还有很多其他的命令和选项,请自行学习验证。
5 pprof监控信息展示——火焰图
火焰图(Flame Graph)是 Bredan Gregg 创建的一种性能分析图表,因为它的样子近似火焰而得名。golang性能监控结果可以转换成火焰图来进行直观展示。火焰图 svg 文件可以通过浏览器打开,它展示调用图的最大优点是火焰图动态的——可以通过点击每个方块来分析它上层概况/下层详细的内容。
火焰图的调用顺序从下到上,每个方块代表一个函数,它上面一层表示这个函数会调用哪些函数,方块的大小代表了占用资源值的多少(例如,CPU使用时间的长短,内存使用的大小等)。火焰图的配色并没有特殊的意义,默认的红、黄配色是为了更像火焰而已。
生成火焰图,有两种方式:go-torch(golang version < 1.10)和golang原生的pprof(golang version < 1.10+的pprof集成了火焰图功能)。
5.1 go-torch
go-torch是uber 开源的一个工具。go-torch可以直接读取 golang 的监控数据文件,并生成一个火焰图的 svg 文件。
go-torch工具使用非常简单,最简单的是使用go-torch的docker镜像运行,无需安装go-torch。
- 首先进行docker安装(ubuntu)。其他操作系统的安装参考codker安装。
- 运行go-rorch镜像
uber/go-torch
。
如果不知道相关命令,可以执行$ sudo docker run uber/go-torch -h
查看go-torch的使用帮助。
$ sudo docker run uber/go-torch -h
Usage:
go-torch [options] [binary] <profile source>
pprof Options:
-u, --url= Base URL of your Go program (default:
http://localhost:8080)
--suffix= URL path of pprof profile (default: /debug/pprof/profile)
-b, --binaryinput= File path of previously saved binary profile. (binary
profile is anything accepted by
https://golang.org/cmd/pprof)
--binaryname= File path of the binary that the binaryinput is for, used
for pprof inputs
-t, --seconds= Number of seconds to profile for (default: 30)
--pprofArgs= Extra arguments for pprof
Output Options:
-f, --file= Output file name (must be .svg) (default: torch.svg)
-p, --print Print the generated svg to stdout instead of writing to
file
-r, --raw Print the raw call graph output to stdout instead of
creating a flame graph; use with Brendan Gregg's flame
graph perl script (see
https://github.com/brendangregg/FlameGraph)
--title= Graph title to display in the output file (default: Flame
Graph)
--width= Generated graph width (default: 1200)
--hash Colors are keyed by function name hash
--colors= set color palette. choices are: hot (default), mem, io,
wakeup, chain, java, js, perl, red, green, blue, aqua,
yellow, purple, orange
--cp Use consistent palette (palette.map)
--reverse Generate stack-reversed flame graph
--inverted icicle graph
Help Options:
-h, --help Show this help message
最重要的命令有五个:
可选参数选项 | 描述 | 默认值 | 备注 |
---|---|---|---|
-u, --url= | golang代码的基础URL——[scheme]://[host]:[port] | http://localhost:8080 | |
--suffix= | pprof profile文件URL路径 | /debug/pprof/profile | |
-t, --seconds= | 执行profile的时间长度,单位是秒 | 30 | |
-f, --file= | 输出文件的名称 | torch.svg | 文件扩展名必须是 .svg |
-p, --print | 将生成的svg文件打印到标准输出,而不是写入文件 |
所有参数都是可选参数。如果没有任何参数,默认情况下,会尝试从http://localhost:8080/debug/pprof/profile 获取监控数据。
例如,从服务器http://10.0.2.15:6060/debug/pprof/block获取阻塞信息,并将生成的svg文件打印到标准输出中,然后信息重定向保存到本地torch.svg文件。
$ sudo docker run uber/go-torch -u http://10.0.2.15:6060 --suffix=/debug/pprof/block -p > torch.svg
INFO[02:33:36] Run pprof command: go tool pprof -raw -seconds 30 http://10.0.2.15:6060/debug/pprof/block
INFO[02:33:36] Printing svg to stdout
第一次执行由于需要安装go-torch相关依赖和镜像,等待时间较长。
执行成功之后,本地会生成一个torch.svg文件。右键通过浏览器打开,可以看到火焰图,如下图所示:
使用go-torch的docker镜像可以在windows操作系统使用。
注:当然了,可以将go-torch和FlameGraph工具分别安装,然后执行go-torch
命令。具体参数和go-torch镜像执行-h
显示的参数相同。此处不再赘述。
5.2 使用golang的pprof查看火焰图
使用go tool pprof可以在Web界面上查看所有类型的资源监控图。
例如,使用pprof查看Web服务器的阻塞监控数据,并将结果展示在6061端口。通过http://localhost:6062/ui/flamegraph即可查看生成的火焰图。
$ go tool pprof -http=:6061 http://localhost:6060/debug/pprof/block
Fetching profile over HTTP from http://localhost:6060/debug/pprof/block
Saved profile in /home/jerry/pprof/pprof.___go_build_main_go.contentions.delay.005.pb.gz
从执行命令的过程,可以看到pprof工具从http://localhost:6060/debug/pprof/block获取监控数据,并保存到本地:/home/jerry/pprof/pprof.___go_build_main_go.contentions.delay.005.pb.gz。然后对该文件进行分析,并启动一个Web服务器:http://localhost:6061。一般会自动弹出一个浏览器并显示结果——默认显示的是graph。但是可以从第一行的菜单中切换View,选择Flame Graph即可显示火焰图。
参考
1 golang pprof 实战
2 Go pprof和火焰图
3 使用 pprof 和火焰图调试 golang 应用
4 go pprof详细理解及使用
5 使用pprof及Go 程序的性能优化