Go进阶-pprof
# PProf是什么
pprof 是用于可视化和分析性能分析数据的工具。
Profiling 是指在程序执行过程中,收集能够反映程序执行状态的数据。 在软件工程中,性能分析(performance analysis,也称为 profiling),是以收集程序运行时信息为手段研究程序行为的分析方法,是一种动态程序分析的方法
go的PProf 主要涉及两个包:
- net/http/pprof:只是使用runtime/pprof包来进行封装了一下,并在http端口上暴露出来。使用 net/http/pprof 可以做到直接看到当前 web 服务的状态,包括 CPU 占用情况和内存使用情况等。如果服务是一直运行的,如 web 应用,可以很方便的使用这种方式 import "net/http/pprof"。
- runtime/pprof: pprof开启后,每隔一段时间就会收集下当前的堆栈信息,获取各个函数占用的CPU以及内存资源;最后通过对这些采样数据进行分析,形成一个性能分析报告。适用于:对于本地只跑一次的程序,例如程序中的某一函数调优,调用 pprof 包提供的函数,手动开启性能数据采集。
# go PProf可以分析哪些指标
- CPU Profiling:CPU 分析,按照一定的频率采集所监听的应用程序 CPU(含寄存器)的使用情况,可确定应用程序在主动消耗 CPU 周期时花费时间的位置
- Memory Profiling:内存分析,在应用程序进行堆分配时记录堆栈跟踪,用于监视当前和历史内存使用情况,以及检查内存泄漏
- Block Profiling:阻塞分析,记录 goroutine 阻塞等待同步(包括定时器通道)的位置
- Mutex Profiling:互斥锁分析,报告互斥锁的竞争情况
# 如何使用
# 工具型应用
如果你的应用程序是运行一段时间就结束退出类型。那么最好的办法是在应用退出的时候把 profiling 的报告保存到文件中,进行分析。对于这种情况,可以使用runtime/pprof
库。 首先在代码中导入runtime/pprof
工具:
import "runtime/pprof"
# CPU性能分析
开启CPU性能分析:
pprof.StartCPUProfile(w io.Writer)
停止CPU性能分析:
pprof.StopCPUProfile()
应用执行结束后,就会生成一个文件,保存了我们的 CPU profiling 数据。得到采样数据之后,使用go tool pprof
工具进行CPU性能分析。
# 内存性能优化
记录程序的堆栈信息
pprof.WriteHeapProfile(w io.Writer)
2
# 服务型应用
如果你使用的是gin框架,那么推荐使用github.com/gin-contrib/pprof (opens new window),在代码中通过以下命令注册pprof相关路由。
pprof.Register(router)
端口假设设置的为6060
访问方式:http://{ip}:6060/debug/pprof 比如本地: http://127.0.0.1:6060/debug/pprof/
# Go pprof页指标
打开页面后,我们看到的是go pprof提供的所有指标类型。以一个列表的形式展示,第一列Count数量,第二列Profile 类型。 其中allocs、goroutine、threadcreate 这种可直接展示结果,profile、heap没有展示,点击详情后开始采样。 比如,点击 profile 后,跳转: $HOST:$PORT/debug/pprof/profile ,默认进行 30s 的 CPU Profiling,得到一个分析用的 profile 文件。
如果遇到错误,表示采样时长大于了 server.writetimeout。 profile duration exceeds server's WriteTimeout
conf/config.yam 中 server相关配置,表示整个 serverHTTP接口的时间, 如果采样时间大于30s 必定会超时,所以就不用进行采样了,直接返回错误。
一般情况下我们可手动指定采样时间: http://127.0.0.1:6060/debug/pprof/profile?seconds=1 (opens new window)参数seconds表示采样时长。默认seconds=30s。
- cpu(CPU Profiling): $HOST/debug/pprof/profile,默认进行 30s 的 CPU Profiling,得到一个分析用的 profile 文件
- block(Block Profiling):$HOST/debug/pprof/block,查看导致阻塞同步的堆栈跟踪
- goroutine:$HOST/debug/pprof/goroutine,查看当前所有运行的 goroutines 堆栈跟踪
- heap(Memory Profiling): $HOST/debug/pprof/heap,查看活动对象的内存分配情况
- mutex(Mutex Profiling):$HOST/debug/pprof/mutex,查看导致互斥锁的竞争持有者的堆栈跟踪
- threadcreate:$HOST/debug/pprof/threadcreate,查看创建新OS线程的堆栈跟踪
# 如何在web ui查看
pprof 可以用来通过多种方式来分析符合 profile.proto 格式的profiling 的数据,比如命令行交互方式、web ui方式、导出text report的方式等。 profile.proto 是用来描述一组调用堆栈和符号化信息的protobuffer,有关协议缓冲区的详细信息,请参阅https://developers.google.com/protocol-buffers (opens new window)只要符合该格式的数据都可以用pprof工具进行分析。
pprof比较常用的方式是web ui,可读性较好。本文主要以web ui方式讲解下详细的字段值。
# 安装Graphviz
安装Graphviz( http://www.graphviz.org/ )后,可以以图表的方式打开,可读性更好。
# mac安装
brew install graphviz 大概率是不会成功
所以使用port命令安装。
- 点击下载 port (opens new window)
- 安装graphviz
sudo port install graphviz
dot -V
输入版本graphviz即安装成功
# 使用
命令行启动,格式:go tool pprof -http=host:port pprof地址
host可省略,默认为localhost,port也可省略,会随机分配一个可用端口。
示例:
使用pprof工具查看堆配置文件:
go tool pprof -http=:6060 http://localhost:8088/debug/pprof/heap?seconds=5
或者查看30秒钟的CPU配置文件:
go tool pprof -http=:6060 http://localhost:8088/debug/pprof/profile
或者在程序中调用runtime.SetBlockProfileRate之后查看goroutine阻止配置文件:
go tool pprof -http=:6060 http://localhost:8088/debug/pprof/block
或者收集5秒钟的执行轨迹
go tool pprof -http=:6060 http://localhost:8088/debug/pprof/trace?seconds=5
或者在程序中调用runtime.SetMutexProfileFraction之后查看争用互斥锁的持有者:
go tool pprof -http=:6060 http://localhost:8088/debug/pprof/mutex
要查看所有可用的配置文件,请在浏览器中打开http://localhost:6060/debug/pprof/
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16