Profiling 是指在程序执行过程中,收集能够反映程序执行状态的数据。
Go 语言自带的 pprof 库就可以分析程序的运行情况,并且提供可视化的功能。它包含两个相关的库:
1.runtime/pprof:对于只跑一次的程序,例如每天只跑一次的离线预处理程序,调用 pprof 包提供的函数,手动开启性能数据采集。
2.net/http/pprof:对于在线服务,对于一个 HTTP Server,访问 pprof 提供的 HTTP 接口,获得性能数据。当然,实际上这里底层也是调用的 runtime/pprof 提供的函数,封装成接口对外提供网络访问。
如何使用:
1)首先是采集数据 - 两种方式
工具型应用
HTTP Server
2)然后就是进行分析了
Report generation:报告生成
Interactive terminal use:交互式终端使用
Web interface:Web 界面
工具型应用
如果你的应用程序是运行一段时间就结束退出类型。
那么最好的办法是在应用退出的时候把 profiling 的报告保存到文件中,进行分析。对于这种情况,可以使用 runtime/pprof 库。 import "runtime/pprof"
1.CPU
// 程序运行时开启统计
pprof.StartCPUProfile(w io.Writer)
// 程序结束时关闭
pprof.StopCPUProfile()
示例:
file, _ := os.Create("./cpu.pprof") // 在当前路径下创建一个cpu.pprof文件
pprof.StartCPUProfile(file) // 往文件中记录CPU profile信息
defer func() {
// 退出之前 停止采集
pprof.StopCPUProfile()
file.Close()
}()
服务型应用
如果你的应用程序是一直运行的,比如 web 应用,那么可以使用 net/http/pprof 库,它能够在提供 HTTP 服务进行分析。
import _ "net/http/pprof"
数据分析
1.交互式命令
通过前面两种方式,获取到数据后即可进行分析。我们可以使用 go tool pprof 命令行工具。go tool pprof [binary] [source]
binary 是应用的二进制文件,用来解析各种符号;
source 表示 profile 数据的来源,可以是本地的文件,也可以是 http 地址。
分析前面保存的 cpu.pprofgo tool pprof cpu.pprof
会进入一个交互式界面,常用的只有 3 个命令。
- top 查看资源较高的调用。
- list 查看问题代码具体位置。
list 代码片段 查看问题代码具体位置. - web
在Web Browser上图形化显示当前的资源监控内容这里就要用到前面安装的 graphviz
我们可以在交互界面输入top(也可以指定个数 比如 top3)来查看程序中占用 CPU 比较多的函数:
2、svg
如果觉得在命令行查看不够直观的话,也可以直接输入web命令,生成 svg 图像进行查看。
关于图形的说明:
每个框代表一个函数,理论上框的越大表示占用的CPU资源越多。
方框之间的线条代表函数之间的调用关系,线条上的数字表示函数调用的次数。
方框中的第一行数字表示当前函数占用CPU的百分比,第二行数字表示当前函数累计占用CPU的百分比。
3、火焰图
也可以使用 go 自带的工具生成火焰图。
获取cpuprofile
go tool pprof http://127.0.0.1:8080/debug/pprof/profile?-seconds=10
时间到后会生成一个类似 pprof.samples.cpu.003.pb.gz 的文件。
生成火焰图:
go tool pprof -http=:8081 ~/pprof/pprof.samples.cpu.001.pb.gz
在浏览器中即可查看到相关信息了 view 中可以选择查询各种内容:
说明:
宽度越大表示占用的 CPU 时间越多。
然后图中的各种条是可以点的,这样看起来更加方便