Golang 性能分析
pprof
是go
自身提供的用于可视化和分析性能数据的工具。在遇到性能问题时,可以使用它进行分析。比如:
- 监控发现进程的CPU 使用率过高;
- 内存占用不断增大,疑似内存泄露;
- 临时内存大量申请后长时间内不释放;
- Goroutine 数量暴涨,并且长时间持续保持;
pprof支持的模式:
- 报告生成
- 交互式终端
- Web UI
pprof可以做什么:
- CPU Profiling:CPU 分析,按照一定的频率采集所监听的应用程序 CPU(含寄存器)的使用情况,可确定应用程序在主动消耗 CPU 周期时花费时间的位置
- Memory Profiling:内存分析,在应用程序进行堆分配时记录堆栈跟踪,用于监视当前和历史内存使用情况,以及检查内存泄漏
- Block Profiling:阻塞分析,记录 goroutine 阻塞等待同步(包括定时器通道)的位置
- Mutex Profiling:互斥锁分析,报告互斥锁的竞争情况
极狐GitLab的Praefect组件使用了Go语言编写,因此在遇到性能问题时,可以使用此工具进行分析。
1. 下载profiles
首先,做一个ssh端口转发,将profile直接下载到你的本地工作站,比如我们将praefect端口9652,转发到本地工作站的6060端口(6060是pprof的常用端口)
# praefect
ssh -N -L 6060:localhost:9652 gitlab-06
# 获取30秒的CPU profiling
curl -o cpu.bin http://localhost:6060/debug/pprof/profile
# 获取5秒的执行跟踪(有一定性能影响)
curl -o trace.bin http://localhost:6060/debug/pprof/trace?seconds=5
# 获取内存使用的profile
curl -o heap.bin http://localhost:6060/debug/pprof/heap
# 获取正在运行的goroutines列表
curl -o goroutines.txt http://localhost:6060/debug/pprof/goroutine?debug=2
# 获取被blocking的goroutine列表
curl -o goroutines-blocking.txt http://localhost:6060/debug/pprof/block
2. 提交profile
将profile文件提交给极狐GitLab技术支持团队。
3. 分析profile
需安装go SDK
yum -y install golang
3.1 查找cpu使用
-
运行
go tool pprof cpu.bin
进入交互模式- 使用
top 30
显示消费cpu最多的30个方法 - 大多数情况下,可以根据cpu累积消耗进行排序:
top 30 -cum
- 使用
-
使用非交互模式:
go tool pprof -top 30 -cum cpu.bin
其中flat代表的是该函数自身代码的执行时长,而cum代表的是该函数自身代码+所有调用的函数的执行时长.
-
选择其中一个方法,并查看其每一行代码的cpu消耗:
go tool pprof -source_path </path/to/go_src> -list <methodname_regexp> cpu.bin
-
网页可视化显示:
go tool pprof -http localhost:8080 cpu.bin
3.1 查看内存使用
-
运行
go tool pprof heap.bin
进入交互模式- 使用
top 30
显示消费内存最多的30个方法 - 大多数情况下,可以根据内存累积消耗进行排序:
top 30 -cum
- 使用
-
使用非交互模式
go tool pprof -top 30 -cum heap.bin
-
选择其中一个方法,并查看其每一行代码的内存消耗:
go tool pprof -source_path </path/to/go_src> -list <methodname_regexp> heap.bin
-
网页可视化显示
需要安装graphviz:
yum -y install graphviz
使用本机8080端口:
go tool pprof -http localhost:8080 heap.bin
图形:
框越大,线越粗,代表占用的资源越多。
分析go应用程序的常驻内存占用情况:
分析go应用程序的内存临时分配情况: