(给Go开发大全
加星标)
来源:wudaijun
https://wudaijun.com/2018/04/go-pprof/
【导读】pprof是golang用于性能分析的工具、可以生成图形和文本报告。在实际项目中对高并发场景下的服务上线前必须经过pprof验证,本文介绍了pprof的用法。
一. pprof 数据采样
pprof 采样数据主要有三种获取方式:
runtime/pprof: 手动调用
runtime.StartCPUProfile
或者runtime.StopCPUProfile
等 API来生成和写入采样文件,灵活性高net/http/pprof: 通过 http 服务获取Profile采样文件,简单易用,适用于对应用程序的整体监控。通过 runtime/pprof 实现
go test: 通过
go test -bench . -cpuprofile prof.cpu
生成采样文件 适用对函数进行针对性测试
1.1 net/http/pprof
在应用程序中导入import _ "net/http/pprof"
,并启动 http server即可:
// net/http/pprof 已经在 init()函数中通过 import 副作用完成默认 Handler 的注册go func() {
log.Println(http.ListenAndServe("localhost:6060", nil))}()
之后可通过 http://localhost:6060/debug/pprof/CMD 获取对应的采样数据。支持的 CMD 有:
goroutine: 获取程序当前所有 goroutine 的堆栈信息。
heap: 包含每个 goroutine 分配大小,分配堆栈等。每分配 runtime.MemProfileRate(默认为512K) 个字节进行一次数据采样。
threadcreate: 获取导致创建 OS 线程的 goroutine 堆栈
block: 获取导致阻塞的 goroutine 堆栈(如 channel, mutex 等),使用前需要先调用
runtime.SetBlockProfileRate
mutex: 获取导致 mutex 争用的 goroutine 堆栈,使用前需要先调用
runtime.SetMutexProfileFraction
以上五个 CMD 都通过runtime/pprof Profile 结构体统一管理,以 Lookup 提供统一查询接口,有相似的返回值(goroutine 堆栈),它们都支持一个 debug URL参数,默认为0,此时返回的采样数据是不可人为解读的函数地址列表,需要结合 pprof 工具才能还原函数名字。debug=1时,会将函数地址转换为函数名,即脱离 pprof 在浏览器中直接查看。对 goroutine CMD来说,还支持 debug=2,此时将以 unrecovered panic 的格式打印堆栈,可读性更高。如启用net/http/pprof
后,http://localhost:6060/debug/pprof/goroutine?debug=2 的响应格式为:
goroutine 18 [chan receive, 8 minutes]:ngs/core/glog.logWorker(0x18b548a, 0x4, 0x7fff5fbffb0e, 0x0, 0x3, 0xc4200e31a0, 0xc4203627c4) /Users/wudaijun/go/src/ngs/core/glog/worker.go:43 +0x19ccreated by ngs/core/glog.newLogger /Users/wudaijun/go/src/ngs/core/glog/glog.go:51 +0xe4goroutine 6 [syscall, 8 minutes]:os/signal.signal_recv(0x0) /usr/local/Cellar/go/1.9.1/libexec/src/runtime/sigqueue.go:131 +0xa7os/signal.loop() /usr/local/Cellar/go/1.9.1/libexec/src/os/signal/signal_unix.go:22 +0x22created by os/signal.init.0 /usr/