Golang 是一个对性能要求很高的语言,
因此语言中自带的 pprof 工具成为我们检测 Golang 开发应用性能的利器。
Google 开发的 Golang 自 2009 年推出,已经日趋成为各大公司开发后端服务使用的语言,有名的基于 Golang 的开源项目有 Docker、Kubernetes 等。当使用 Golang 开发服务后端服务时,难免产生性能问题,如内存泄漏、Goroutine 卡死等,Golang 是一个对性能要求很高的语言,因此语言中自带的 pprof
工具成为我们检测 Golang 开发应用性能的利器。
Profiling
一般翻译为 画像,在计算机领域,我们可以将其理解为当前应用状态的画像。当程序性能不佳时,我们希望知道应用在 什么地方 耗费了 多少 CPU、memory。下面将介绍如何使用这一工具。
Golang 服务主要关注的应用运行情况包含以下几种
- CPU profile:报告程序的 CPU 使用情况,按照一定频率去采集应用程序在 CPU 和寄存器上面的数据
- Memory Profile(Heap Profile):报告程序的内存使用情况
- Block Profiling:报告 goroutines 不在运行状态的情况,可以用来分析和查找死锁等性能瓶颈
- Goroutine Profiling:报告 goroutines 的使用情况,有哪些 goroutine,它们的调用关系是怎样的
两种使用方式
go 语言提供了 runtime/pprof
和 net/http/pprof
两个库,这部分我们讲讲它们的用法以及使用场景。
工具型应用
工具型应用: 如果应用是命令行应用,程序启动后,在一段时间(短期运行)内会随着处理完成而关闭。
工具型应用使用使用 runtime/pprof
库, 可以产生 dump 文件,应用退出的时候把 profiling 的报告保存到文件中,进行分析。
将 runtime/pprof
导入 main.go
1 | import "runtime/pprof" |
其中 pprof
封装了很好的接口供我们使用,比如要想进行 CPU Profiling,可以调用 pprof.StartCPUProfile()
方法,它会对当前应用程序进行 CPU profiling,并写入到提供的参数中(w io.Writer)
,要停止调用 StopCPUProfile()
即可。
去除错误处理只需要以下内容,一般把部分内容写在 main.go 文件中,应用程序启动之后就开始执行:
1 | f, err := os.Create(*cpuprofile) |
应用执行结束后,就会生成一个文件,保存了我们的 CPU profiling 数据。
想要获得内存的数据,直接使用 WriteHeapProfile 就行,不用 start 和 stop 这两个步骤了:
1 | f, err := os.Create(*memprofile) |
服务型应用
服务型应用: 如果应用是一直运行(长期运行)的,比如 web 应用,那么可以使用 net/http/pprof
库,它能够在提供 HTTP 服务进行分析。
服务型应用使用 net/http/pprof
库, 其中 net/http/pprof
使用 runtime/pprof
包来进行封装,并在 http 端口上暴露出来。
如果使用了默认的 http.DefaultServeMux
(通常是代码直接使用 http.ListenAndServe("0.0.0.0:8000", nil)
),只需要添加一行:
1 | import _ "net/http/pprof" |
如果应用使用了自定义的 Mux
,则需要手动注册一些路由规则:
1 | r.HandleFunc("/debug/pprof/", pprof.Index) |
服务起来之后,就会多多一条路由,如 http://127.0.0.1:8000/debug/pprof
,有以下输出
1 | /debug/pprof/ |
这个路径下还有几个子页面:
/debug/pprof/profile
:访问这个链接会自动进行 CPU profiling,持续 30s,并生成一个文件供下载/debug/pprof/heap
: Memory Profiling 的路径,访问这个链接会得到一个内存 Profiling 结果的文件/debug/pprof/block
:block Profiling 的路径
获取和分析 Profiling 数据
获取的 Profiling 数据是动态的,要想获得有效的数据,请保证应用处于较大的负载(比如正在生成中运行的服务,或者通过其他工具模拟访问压力)。否则如果应用处于空闲状态,得到的结果可能没有任何意义。
能通过对应的库获取想要的 Profiling 数据之后(不管是文件还是 http),下一步就是要对这些数据进行保存和分析,我们可以使用 go tool pprof
命令行工具。
/debug/pprof/profile
/debug/pprof/heap
/debug/pprof/block
/debug/pprof/goroutines
go tool pprof 工具可以对以上各个路径 prof 文件进行更详细的分析,可以生成调用关系图和火焰图。
生成调用关系图
- 安装 graphviz 工具
- 分析工具使用命令 go tool pprof [binary][source]
- 生成关系调用图
安装 graphviz 工具
1
2
3
4
5# Centos 6/7
# yum install -y graphviz
# Centos 8
# dnf install -y graphviz分析工具使用命令 go tool pprof
go tool pprof demo demo.prof (pprof) web #生成调用关系图,demo.svg文件