工具简介
pprof 是 Go 语言的性能剖析工具,用于分析和优化 Go 程序的性能。它是 Go 标准库中的一个子命令,可以与 Go 工具链一起使用。pprof 支持多种类型的剖析数据,并可以生成交互式的可视化报告,帮助开发人员找出程序中的性能瓶颈。
pprof 有两种使用方式
- 导出方式:通过在程序中调用 net/http/pprof 包中的函数,可以在程序运行时导出剖析数据,并使用浏览器查看可视化报告。可以通过
import _"net/http/pprof",并启动http server
go func() { log.Println(http.ListenAndServe("localhost:6060", nil)) }()
通过http://localhost:6060/debug/pprof/CMD获得对应的采样数据。
- 命令行方式:通过在程序运行后使用 go tool pprof 命令,导入已经生成的剖析数据文件,并查看分析结果。
实践过程
通过包含net/http/pprof包,这会自动注册pprof的handle到http server,启动该程序后,通过访问- http://localhost:6060/debug/pprof/浏览器会得到一个可视化报告,其中会有相关的性能分析报告
页面上展示了可用的程序运行采样数据,分别有
| 类型 | 描述 | 备注 |
|---|---|---|
| allocs | 内存分配情况的采样信息 | 可以用浏览器打开,但可读性不高 |
| blocks | 阻塞操作情况的采样信息 | 可以用浏览器打开,但可读性不高 |
| cmdline | 显示程序启动命令及参数 | 可以用浏览器打开,这里会显示 |
| goroutine | 当前所有协程的堆栈信息 | 可以用浏览器打开,但可读性不高 |
| heap | 堆上内存使用情况的采样信息 | 可以用浏览器打开,但可读性不高 |
| mutex | 锁争用情况的采样信息 | 可以用浏览器打开,但可读性不高 |
| profile | CPU 占用情况的采样信息 | 浏览器打开会下载文件 |
| threadcreate | 系统线程创建情况的采样信息 | 可以用浏览器打开,但可读性不高 |
由于直接阅读采样信息缺乏直观性,我们需要借助go tool pprof命令来排查问题
通过在powershell中使用go tool pprof http://localhost:6060/debug/pprof/profile命令可以查看CPU的使用情况,常用的命令有top,list等,使用web命令可以更加清晰的查看CPU的使用情况,但这需要下载对应的graphviz,下载连接为[graphviz.gitlab.io/download/
- opN: 输入 top 命令,默认显示 flat 前10的函数调用,可使用 -cum 以 cum 排序
- list Func: 显示函数名以及每行代码的采样分析
- web: 生成 svg 热点图片,可在浏览器中打开,可使用 web Func 来过滤指定函数相关调用树
在top命令后会弹出对应的信息,其对应的解释为:
- flat 当前函数本身的执行耗时
- flat% flat占CPU总时间的比例
- sum% 上面的每一行的flat%总和
- cum 指当前函数本身加上其调用函数的总耗时
- cum% cum占CPU总时间的比例
为了可以更好看到可视化效果,我们可以直接在浏览器上访问go tool pprof -http=:8080 <http://localhost:6060/debug/pprof/goroutine>该地址,最后一个单词代表我们想查看的类型信息,例如如果是heap则查看的是内存信息。
需要注意的是,如果我们想查看GC的情况,powershell中通过使用$env:GODEBUG = "gctrace=1"; .\go-pprof-practice.exe | Select-String "gc"命令查看频繁的内存回收,与其他操作系统不同的是调用GODEBUG = "gctrace=1"命令需要使用env标注,不可以直接使用grep进行筛查对应的命令为Select-string
对于其他类型的查看,均可通过类型的操作实现,这些可视化效果通过浏览器上的信息也可以方便的实现
- 通过使用
go tool pprof http://localhost:6060/debug/pprof/allocs查看内存分配情况, - 通过使用
go tool pprof http://localhost:6060/debug/pprof/goroutline可以查看协程泄漏 - 通过使用
go tool pprof http://localhost:6060/debug/pprof/mutex可以查看锁的竞争 - 通过使用
go tool pprof http://localhost:6060/debug/pprof/block可以查看阻塞情况
通过上述的分析,我们可以把该实战过程中的代码问题得到很好的解决,当然为了定位问题,我们可以通过top,list,web一系列操作找到问题所在。