pprof是Go的性能分析工具,在程序运行过程中,可以记录程序的运行信息,可以是CPU使用情况、内存使用情况、goroutine运行情况等,当需要性能调优或者定位Bug时候,这些记录的信息是相当重要。
go 对于 profiling 支持的比较好,标准库就提供了profile 库 runtime/pprof 和 net/http/pprof,而且也提供了很多好用的可视化工具来辅助开发者做 profiling。
对于在线服务,对于一个 HTTP Server,访问 pprof 提供的 HTTP 接口,获得性能数据。
pprof 的应用场景主要分为两种:
1. 服务型应用,例如 web 服务器等各种服务类型端的性能分析;
2. 工具型应用,例如一些命令行工具,执行完毕后直接退出的应用;
工具型应用性能分析基于 "runtime/pprof" 包,将性能数据存放在文件中 :
package main
import (
"fmt"
"os"
"runtime/pprof"
)
func main() {
// 创建 cup 数据记录文件
cpuProfile, err := os.Create("./cpu_profile")
if err != nil {
fmt.Printf("创建文件失败:%s", err.Error())
return
}
defer cpuProfile.Close()
// 创建内存数据记录文件
memProfile, err := os.Create("./mem_profile")
if err != nil {
fmt.Printf("创建文件失败:%s", err.Error())
return
}
defer memProfile.Close()
//采集CPU信息
pprof.StartCPUProfile(cpuProfile)
defer pprof.StopCPUProfile()
//采集内存信息
pprof.WriteHeapProfile(memProfile)
// 执行一个逻辑
for i := 0; i < 9999; i++ {
fmt.Println("pprof 工具型测试")
}
println("-- mian done --")
}
执行上面的代码后,会产生2个性能数据文件 : cpu_profile 和 mem_profile,可以使用 go tool pprof 命令查看数据 :
# 01. 执行命令
# cup 使用数据
go tool pprof .\cpu_profile
# 内存使用数据
# go tool pprof .\mem_profile
# 02. 回显 :
PS ...\goDemo> go tool pprof .\cpu_profile
File: main.exe
Build ID: ...\main.exe2023-10-11 13:54:05.4308623 +0800 CST
Type: cpu
Time: Oct 11, 2023 at 1:54pm (CST)
Duration: 979.59ms, Total samples = 510ms (52.06%)
Entering interactive mode (type "help" for commands, "o" for options)
(pprof)
# 03. 输入命令继续
top5
# 数据内容 :
flat flat% sum% cum cum%
510ms 100% 100% 510ms 100% runtime.cgocall
0 0% 100% 510ms 100% fmt.Fprintln
0 0% 100% 510ms 100% fmt.Println
0 0% 100% 510ms 100% internal/poll.(*FD).Write
0 0% 100% 510ms 100% internal/poll.(*FD).writeConsole
列信息字段作用 :
flat:函数在 CPU 上运行的时间
flat%:函数在CPU上运行时间的百分比
sum%:是从第一行到当前行所有函数累加使用 CPU 的比例,如第二行sum=53.85=30.77+23.08
cum:这个函数以及子函数运行所占用的时间,应该大于等于flat
cum%:这个函数以及子函数运行所占用的比例,应该大于等于flat%
最后一列:函数的名字
您还可以开启一个 web 服务,以 web 形式查看性能数据 :
go tool pprof -http=:8808 .\mem_profile
注意 : 需要安装 graphviz
Graphviz 是一款由 AT&T Research 和 Lucent Bell 实验室开源的可视化图形工具,可以很方便的用来绘制结构化的图形网络,支持多种格式输出。Graphviz 输入是一个用 dot 语言编写的绘图脚本,通过对输入脚本的解析,分析出其中的点、边及子图,然后根据属性进行绘制。Graphviz layout 以简单的文本语言描述图形,并以实用的格式制作图表,如用于网页的 images 和 SVG ;用于放入在其它文件中或显示在交互式图形浏览器中的 PDF 和 Postscript 。
官网 : https://www.graphviz.org/
下载及安装 graphviz : https://www.graphviz.org/download/
go tool pprof -http=:8808 .\mem_profile
会打开一个浏览器窗口,以图形界面形式展示性能数据 :
对于服务类型的应用,主要在服务内部匿名引入 net/http/pprof 包,然后通过 HTTP 访问 pprof 页面。
package main
import (
"fmt"
"net/http"
_ "net/http/pprof"
)
func main() {
http.HandleFunc("/", Test)
err := http.ListenAndServe(":8080", nil)
if err != nil {
fmt.Println("ListenAndServe Err:", err.Error())
return
}
}
func Test(resp http.ResponseWriter, req *http.Request) {
fmt.Fprintln(resp, "")
}
上面的代码开启了一个 HTTP 服务,端口为 8080,可以通过浏览器访问 :
http://localhost:8080/ 进行测试。
查看服务性能数据 :
执行http://localhost:8080/debug/pprof/可以看到画像信息:
项目功能描述
allocs:过去所有内存分配的采样
block:导致同步基元阻塞的堆栈跟踪
cmdline:当前程序的命令行调用
goroutine:堆栈所有当前goroutine的跟踪。使用debug=2作为查询参数,以与未恢复的死机相同的格式导出。
heap:活动对象的内存分配的采样。您可以指定gc GET参数以在获取堆样本之前运行gc。
mutex:争用互斥体持有者的堆栈跟踪
profile:CPU配置文件。您可以在seconds GET参数中指定持续时间。获取配置文件后,使用go tool pprof命令来调查该配置文件。
threadcreate:导致创建新操作系统线程的堆栈跟踪
trace:当前程序执行的跟踪。您可以在seconds GET参数中指定持续时间。获取跟踪文件后,使用go tool trace命令来调查跟踪。
记录指定时间段内的性能数据 :
浏览器访问 : http://localhost:8080/debug/pprof/profile?seconds=10
10 秒( 可以通过参数设置监控时长 )后 ( 期间可以访问网站首页或者使用 ab 进行压测 ) 会自动下载得到一个性能文件 : profile。
在 profile 同目录下执行 :
go tool pprof .\profile
# 回显
Type: cpu
...
# 继续输入
top
# 显示
Showing top 10 nodes out of 146
flat flat% sum% cum cum%
1700ms 28.05% 28.05% 1710ms 28.22% runtime.cgocall
560ms 9.24% 37.29% 560ms 9.24% runtime.stdcall1
450ms 7.43% 44.72% 460ms 7.59% runtime.stdcall6
350ms 5.78% 50.50% 1910ms 31.52% github.com/cnlesscode/graceMessageQueue/kernel.SaveMsgToDisk
310ms 5.12% 55.61% 320ms 5.28% runtime.mapaccess1_faststr
120ms 1.98% 57.59% 150ms 2.48% runtime.chanrecv
110ms 1.82% 59.41% 570ms 9.41% runtime.netpoll
80ms 1.32% 60.73% 80ms 1.32% runtime.siftupTimer
70ms 1.16% 61.88% 70ms 1.16% runtime.casgstatus
70ms 1.16% 63.04% 80ms 1.32% runtime.lock2
# 使用 list 命令查看耗时函数
list github.com/cnlesscode/graceMessageQueue/kernel.SaveMsgToDisk
以 web 形式查看数据
go tool pprof -http=:9090 .\profile