You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
性能分析的目的是发现程序瓶颈,为代码优化提供指导,以及对优化结果进行量化验证。主要从内存和 CPU 使用两个维度进行分析。
Go 官方提供了功能强大的包和工具 pprof。使用过程大致分成两步:
收集运行指标数据,生成 pprof 文件;
使用命令工具 go tool pprof 解析 pprof 文件,进行分析;
下面将详细阐述。
指标收集
有三种实践方式,前两种是在程序内(一般是 main 函数内)导入包 net/http/pprof,或者使用 runtime/pprof 包。
区别是前者提供 HTTP API 接口,可以直接在 Web 页面查看,而后者是在将运行数据写入到本地文件保存。一般都选择使用前者,因为使用更简单,使用 Web 交互也更方便,还可实时查看。
package main
import (
"net/http"
_ "net/http/pprof"
)
func main() {
// some code
http.ListenAndServe("127.0.0.1:6060", nil)
}
需要注意的是,可以指定请求参数 seconds 来收集指定时间内的数据,例如 CPU profile: go tool pprof http://127.0.0.1:6060/debug/pprof/profile?seconds=30。
我们知道,这样生成的数据文件进行数据分析才更有意义,因为一般我们都是期望对程序某个运行时间段内进行分析。
还有一种方式是使用 go test 做性能测试,直接导出 pprof 文件:
go test -cpuprofile cpu.prof -memprofile mem.prof -bench .
很明显,这种方式更适合对程序某个模块(函数)做性能分析,上面两种方式用来做程序整体的性能分析。
数据分析
生成 pprof 文件后,有两种分析方式:命令交互式和 Web 图形式。两种方式都是使用命令工具 go tool pprof。
pprof -http=":8081" [binary] ./profile 创建 Web 服务,可以直接在 Web 页面查看调用图,火焰图甚至源代码等,非常方便,直观;
结合前面“指标收集”阶段,可以使用 API 方式获取 pprof 数据,这里还可以直接使用 url 请求来分析,以分析 5 分钟内 CPU 使用情况为例:
go tool pprof -http="127.0.0.1:8081" main.go http://127.0.0.1:6060/debug/pprof/profile?seconds=300
这么做的好处是可以实时对 CPU,内存等维度进行分析,且可以任意切换维度。
火焰图
火焰图是常用的性能分析工具,非常直观。对于很多语言来说(比如 Lua)生成火焰图的过程是很繁琐的,要借助一堆工具。在 Go 1.11 之前一般也是借助开源工具 go-torch,不过 Go 1.11 对 go tool pprof 进行了功能增强,可以直接生成火焰图等图形,因此,go-torch 项目也已经废弃了。
y 轴表示调用栈,每一层都是一个函数。调用栈越深,火焰就越高,顶部就是正在执行的函数,下方都是它的父函数。
x 轴表示抽样数,如果一个函数在 x 轴占据的宽度越宽,就表示它占有率更高,即执行的时间长或内存大。注意,x 轴不代表时间,而是所有的调用栈合并后,按字母顺序排列的。
Go 程序性能分析
性能分析的目的是发现程序瓶颈,为代码优化提供指导,以及对优化结果进行量化验证。主要从内存和 CPU 使用两个维度进行分析。
Go 官方提供了功能强大的包和工具
pprof
。使用过程大致分成两步:pprof
文件;go tool pprof
解析pprof
文件,进行分析;下面将详细阐述。
指标收集
有三种实践方式,前两种是在程序内(一般是 main 函数内)导入包 net/http/pprof,或者使用 runtime/pprof 包。
区别是前者提供 HTTP API 接口,可以直接在 Web 页面查看,而后者是在将运行数据写入到本地文件保存。一般都选择使用前者,因为使用更简单,使用 Web 交互也更方便,还可实时查看。
浏览器访问
http://127.0.0.1:6060/debug/pprof/
,可以看到如下内容:需要注意的是,可以指定请求参数
seconds
来收集指定时间内的数据,例如 CPU profile:go tool pprof http://127.0.0.1:6060/debug/pprof/profile?seconds=30
。我们知道,这样生成的数据文件进行数据分析才更有意义,因为一般我们都是期望对程序某个运行时间段内进行分析。
还有一种方式是使用
go test
做性能测试,直接导出pprof
文件:go test -cpuprofile cpu.prof -memprofile mem.prof -bench .
很明显,这种方式更适合对程序某个模块(函数)做性能分析,上面两种方式用来做程序整体的性能分析。
数据分析
生成
pprof
文件后,有两种分析方式:命令交互式和 Web 图形式。两种方式都是使用命令工具go tool pprof
。go tool pprof ./profile
进入交互模式,可以查看 top, 生成图片(需要安装 Graphviz 支持)或生成 DOT 格式图片(需要使用 Graphviz 转换成常见图片格式)等;pprof -http=":8081" [binary] ./profile
创建 Web 服务,可以直接在 Web 页面查看调用图,火焰图甚至源代码等,非常方便,直观;结合前面“指标收集”阶段,可以使用 API 方式获取
pprof
数据,这里还可以直接使用 url 请求来分析,以分析 5 分钟内 CPU 使用情况为例:go tool pprof -http="127.0.0.1:8081" main.go http://127.0.0.1:6060/debug/pprof/profile?seconds=300
这么做的好处是可以实时对 CPU,内存等维度进行分析,且可以任意切换维度。
火焰图
火焰图是常用的性能分析工具,非常直观。对于很多语言来说(比如 Lua)生成火焰图的过程是很繁琐的,要借助一堆工具。在 Go 1.11 之前一般也是借助开源工具 go-torch,不过 Go 1.11 对
go tool pprof
进行了功能增强,可以直接生成火焰图等图形,因此,go-torch 项目也已经废弃了。火焰图就是看顶层的哪个函数占据的宽度最大。只要有"平顶"(plateaus),就表示该函数可能存在性能问题。
小结
前面介绍了 Go 程序性能分析的过程,需要主要的是,只有对程序进行压测(程序达到瓶颈)的情况下,进行性能分析才有意义。
下面是工作中的一次实践过程 --- 程序压测与性能分析总结报告,作为参考。
参考
附:常用命令
top
查看进程 CPU,内存等使用情况free
查看系统内存使用情况uname -a
查看系统内核信息cat /proc/cpuinfo| grep "physical id"| sort| uniq| wc -l
CPU 个数cat /proc/cpuinfo| grep "cpu cores"| uniq
CPU 核数The text was updated successfully, but these errors were encountered: