工欲善其事必先利其器, 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/heapgo tool pprof http://localhost:6060/debug/pprof/blockgo tool pprof http://localhost:6060/debug/pprof/mutexgo tool pprof http://localhost:6060/debug/pprof/goroutinepprof 还提供了可视化界面的查看, 有两种操作方式(需要提前安装 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