工欲善其事必先利其器, java 中有 async-profile、 arthas、jstack/jmap/jstat
等一系列工具来辅助排查性能问题
在 linux 下,常用的调试定位工具:
go 语言中在内存、性能排查方面主要使用 pprof
:
pprof 的使用场景:
pprof 的使用方式:
pprof 是入侵式的, 需要先引入依赖:
"net/http"
_ "net/http/pprof"
然后显示的开启一个端口(最好是单独启一个协程, 如果程序是一个web服务, 避免和web Server公用同一个端口):
go func() {
log.Println(http.ListenAndServe(":6060", nil))
}()
我们引入了两个包: net/http
和 net/http/pprof
, 前者是启动一个http服务监听一个端口, 后者做了几件事情:
在 init
里面注册路由:
func init() {
http.HandleFunc("/debug/pprof/", Index)
http.HandleFunc("/debug/pprof/cmdline", Cmdline)
http.HandleFunc("/debug/pprof/profile", Profile)
http.HandleFunc("/debug/pprof/symbol", Symbol)
http.HandleFunc("/debug/pprof/trace", Trace)
}
实现ServeHTTP
并注册以下几个路由:
var profileSupportsDelta = map[handler]bool{
"allocs": true,
"block": true,
"goroutine": true,
"heap": true,
"mutex": true,
"threadcreate": true,
}
直接访问ip:port/debug/pprof
可以看到一些子页面, 类似如下:
/debug/pprof/
Types of profiles available:
Count Profile
95 allocs
3 block
0 cmdline
55 goroutine
95 heap
1 mutex
0 profile
5 threadcreate
0 trace
full goroutine stack dump
我们常用的一些性能分析数据可以从这些页面得到:
/debug/pprof/profile
,默认进行 30s 的 CPU Profiling,得到一个分析用的 profile 文件/debug/pprof/block
,查看导致阻塞同步的堆栈跟踪/debug/pprof/goroutine
,查看当前所有运行的 goroutines 堆栈跟踪/debug/pprof/heap
,查看活动对象的内存分配情况/debug/pprof/mutex
,查看导致互斥锁的竞争持有者的堆栈跟踪/debug/pprof/threadcreate
,查看创建新 OS 线程的堆栈跟踪go tool pprof http://localhost:6060/debug/pprof/profile?seconds=60
执行该命令后,需等待 60 秒(可调整 seconds 的值),pprof 会进行 CPU Profiling。结束后将默认进入 pprof 的交互式命令模式,可以对分析的结果进行查看或导出。交互模式下具体的命令可以通过 help 查看命令说明
go tool pprof http://localhost:6060/debug/pprof/profile?seconds=60
Fetching profile over HTTP from http://localhost:6060/debug/pprof/profile?seconds=60
Saved profile in /root/pprof/pprof.pprof-amd64-linux.samples.cpu.001.pb.gz
File: pprof-amd64-linux
Type: cpu
Time: Jun 27, 2023 at 7:56pm (CST)
Duration: 60.14s, Total samples = 32.90s (54.71%)
Entering interactive mode (type "help" for commands, "o" for options)
#### CPU Profile
(pprof) top
Showing nodes accounting for 32.88s, 99.94% of 32.90s total
Dropped 15 nodes (cum <= 0.16s)
flat flat% sum% cum cum%
32.88s 99.94% 99.94% 32.88s 99.94% github.com/wolfogre/go-pprof-practice/animal/felidae/tiger.(*Tiger).Eat
0 0% 99.94% 32.88s 99.94% github.com/wolfogre/go-pprof-practice/animal/felidae/tiger.(*Tiger).Live
0 0% 99.94% 32.90s 100% main.main
0 0% 99.94% 32.90s 100% runtime.main
上面的示例在结束 CPU Profiling 后, 通过 top 命令查看CPU占用久的函数, top 输出各列的含义:
go tool pprof http://localhost:6060/debug/pprof/heap
go tool pprof http://localhost:6060/debug/pprof/block
go tool pprof http://localhost:6060/debug/pprof/mutex
go tool pprof http://localhost:6060/debug/pprof/goroutine
pprof 还提供了可视化界面的查看, 有两种操作方式(需要提前安装 graphviz
支持):
web
, 此刻会打开浏览器跳转.pb.gz
文件, 拉到本地后使用命令如: go tool pprof -http=:8081 ./pprof.pprof-amd64-linux.goroutine.001.pb.gz
即可跳转浏览器查看(有top占用、火焰图等信息)
备注: 这里生成的文件也可以采取 curl 生成: curl -o cpu.prof http://localhost:6060/debug/pprof/profile