golang代码的性能监控使用pprof包来做。pprof有两个包:
runtime/pprofnet/http/pprofruntime/pprof
2 pprof监控内容
pprof监控的内容项目入下表所示。
类型 | 描述 | 备注 |
---|---|---|
allocs | 内存分配情况的采样信息 | 可以用浏览器打开,但可读性不高 |
blocks | 阻塞操作情况的采样信息 | 可以用浏览器打开,但可读性不高 |
cmdline | 显示程序启动命令及参数 | 可以用浏览器打开,但可读性不高 |
goroutine | 当前所有协程的堆栈信息 | 可以用浏览器打开,但可读性不高 |
heap | 堆上内存使用情况的采样信息 | 可以用浏览器打开,但可读性不高 |
mutex | 锁争用情况的采样信息 | 可以用浏览器打开,但可读性不高 |
profile | CPU 占用情况的采样信息 | 浏览器打开会下载文件 |
threadcreate | 系统线程创建情况的采样信息 | 可以用浏览器打开,但可读性不高 |
trace | 程序运行跟踪信息 | 浏览器打开会下载文件 |
go tool pprof [binary] file
3.1 非Web应用程序
runtime/pprof
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应用程序
net/http/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监控信息使用
go tool pprof [binary] file
toplistlist 代码片段webweb.svg.svg.svg.svg
help
svgpdfpng
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。
$ 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] | ||
--suffix= | pprof profile文件URL路径 | /debug/pprof/profile | |
-t, --seconds= | 执行profile的时间长度,单位是秒 | 30 | |
-f, --file= | 输出文件的名称 | torch.svg | 文件扩展名必须是 .svg |
-p, --print | 将生成的svg文件打印到标准输出,而不是写入文件 |
所有参数都是可选参数。如果没有任何参数,默认情况下,会尝试从 获取监控数据。
例如,从服务器获取阻塞信息,并将生成的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-h
5.2 使用golang的pprof查看火焰图
使用go tool pprof可以在Web界面上查看所有类型的资源监控图。
例如,使用pprof查看Web服务器的阻塞监控数据,并将结果展示在6061端口。通过即可查看生成的火焰图。
$ 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 程序的性能优化