pprof 功能有2种开启方式,对应两种包:
- net/http/pprof:使用服务器的场景
- runtime/pprof:使用在非服务器应用程序的场景
这两个本质上是一致的,net/http/pporf 也只是在 runtime/pprof 上的一层 web 封装
pprof 支持四种类型的分析:
- CPU
CPU 分析,采样消耗 cpu 的调用,这个一般用来定位排查程序里耗费计算资源的地方。 - Memory
内存分析,一般用来排查内存占用,内存泄露等问题。 - Block
阻塞分析,会采样程序里阻塞的调用情况。 - Mutex
互斥锁分析,采样互斥锁的竞争情况。
一个简单的例子
package main
import (
"fmt"
"net/http"
_ "net/http/pprof"
)
var datas []string
func add(s string) []string {
datas = append(datas, s)
return datas
}
func main() {
go func() {
for {
fmt.Println(add("hello world"))
}
}()
http.ListenAndServe("0.0.0.0:6060", nil)
}
直接web访问:http://127.0.0.1:6060/debug/pprof/
需要注意的是:默认情况下是不会追踪 block 和 mutex 信息的,如果想要看这2个信息,需要在代码中加入:
runtime.SetBlockProfileRate(1) // 开启对阻塞操作的跟踪,block
runtime.SetMutexProfileFraction(1) // 开启对锁调用的跟踪,mutex
这上面最能看出来的是 goroutine,可以从上面看出当前系统 goroutine 数量,这个对于定位 goroutine 数量泄漏非常方便。
分析数据
用 go tool pprof
工具可进行数据的分析。
命令格式:
go tool pprof [binary] [source]
- binary 是应用的二进制文件,用来解析各种符号,也可以不填。
- source 表示 profile 数据的来源,可以是本地的文件,也可以是 http 地址。
举例:
# cpu profile
go tool pprof http://127.0.0.1:6060/debug/pprof/profile
运行上述命令将会采样半分钟的cpu数据并进入一个交互界面,可以通过输入命令查看分析结果:
接着我们可以输入一些命令,来获取一些信息:
-
top
列出cpu占用高的函数
还可以使用
top20
查看前20个函数。 list
还可以使用list 函数名
命令查看具体的函数分析,例如执行list logicCode查看我们编写的函数的详细分析。traces
列出函数调用栈
-
svg
可以生成图形的形式查看当前资源监控。需要事先安装 graphviz。
内存分配相关的数据查看
- 查看当前内存分配数据
go tool pprof -inuse_space http://127.0.0.1:8080/debug/pprof/heap go tool pprof -inuse_objects http://127.0.0.1:8080/debug/pprof/heap
- 查看总共的内存分配数据
go tool pprof -alloc_space http://127.0.0.1:8080/debug/pprof/heap go tool pprof -alloc_objects http://127.0.0.1:8080/debug/pprof/heap
火焰图
golang性能监控结果可以转换成火焰图来进行直观展示。
有两种方式:go-torch(golang version < 1.10)和 golang原生的pprof(golang version > 1.10+的pprof集成了火焰图功能)。
这里只介绍golang官方的火焰图。
go tool pprof -http=:6061 http://localhost:6060/debug/pprof/profile
从执行命令的过程,可以看到pprof工具 http://localhost:6060/debug/pprof/profile 获取监控数据,并保存到地:xxx.005.pb.gz。
然后对该文件进行分析,并启动一个Web服务器:http://localhost:6061。可以从第一行的菜单中切换View,选择Flame Graph即可显示火焰图。
火焰图的调用顺序从下到上,每个方块代表一个函数,它上面一层表示这个函数会调用哪些函数,方块的大小代表了占用资源值的多少(例如,CPU使用时间的长短,内存使用的大小等)。
pprof 与测试的结合
go test
命令有两个参数和 pprof 相关,它们分别指定生成的 CPU 和 Memory profiling 保存的文件:
- cpuprofile:cpu profiling 数据要保存的文件地址
- memprofile:memory profiling 数据要报文的文件地址
比如下面执行测试的同时,也会执行 CPU profiling,并把结果保存在 cpu.prof 文件中:
go test -bench . -cpuprofile=cpu.prof
参考资料
1、Go语言之pprof的性能调优
2、https://mp.weixin.qq.com/s/SvzMEdhxHfI9hYU62r1C7g
3、https://zhuanlan.zhihu.com/p/396363069
4、https://zhuanlan.zhihu.com/p/265080950