PProf
PProf 是什么
PProf是 golang 官方提供的性能调优分析工具,用于分析和优化Go程序的性能。
PProf通过收集和分析程序的运行时数据来生成性能分析报告。它使用Go语言的运行时特性,如代码注释和特殊的程序运行标记,来收集性能数据。PProf可以检测和测量程序中的CPU利用率、内存分配、阻塞等情况,并生成可视化的报告和图表,以帮助开发人员理解程序的行为和性能瓶颈。
PProf 以 profile.proto 读取分析样本的集合,并生成报告以可视化并帮助分析数据(支持文本和图形报告)。 profile.proto 是一个 Protobuf v3 的描述文件,它描述了一组 callstack 和 symbolization 信息, 作用是统计分析的一组采样的调用栈,是很常见的 stacktrace 配置文件格式。
有哪几种采样方式
- runtime/pprof:采集程序(非 Server)的指定区块的运行数据进行分析。
- net/http/pprof:基于 HTTP Server 运行,并且可以采集运行时数据进行分析。
- go test:通过运行测试用例,并指定所需标识来进行采集。
支持什么使用模式
- Report generation:报告生成。
- Interactive terminal use:交互式终端使用。
- Web interface:Web 界面。
可以做什么
- CPU Profiling:CPU 分析,按照一定的频率采集所监听的应用程序 CPU(含寄存器)的使用情况,可确定应用程序在主动消耗 CPU 周期时花费时间的位置。
- Memory Profiling:内存分析,在应用程序进行堆分配时记录堆栈跟踪,用于监视当前和历史内存使用情况,以及检查内存泄漏。
- Block Profiling:阻塞分析,记录 Goroutine 阻塞等待同步(包括定时器通道)的位置,默认不开启,需要调用
runtime.SetBlockProfileRate
进行设置。 - Mutex Profiling:互斥锁分析,报告互斥锁的竞争情况,默认不开启,需要调用
runtime.SetMutexProfileFraction
进行设置。 - Goroutine Profiling: Goroutine 分析,可以对当前应用程序正在运行的 Goroutine 进行堆栈跟踪和分析。这项功能在实际排查中会经常用到,因为很多问题出现时的表象就是 Goroutine 暴增,而这时候我们要做的事情之一就是查看应用程序中的 Goroutine 正在做什么事情,因为什么阻塞了,然后再进行下一步。
HTTP Server 使用举例
1.代码
提供一个http server,最重要一步,就是在 import 中添加 _ "net/http/pprof" 的引用
import (
"log"
"net/http"
"time"
_ "net/http/pprof"
)
var datas []string
func main() {
go func() {
for {
log.Printf("len: %d", Add("go-programming-tour-book"))
time.Sleep(time.Millisecond * 10)
}
}()
_ = http.ListenAndServe("0.0.0.0:6060", nil)
}
func Add(str string) int {
data := []byte(str)
datas = append(datas, string(data))
return len(datas)
}
下载安装 pprof 包,go get github.com/google/pprof 。
启动程序,访问 http://127.0.0.1:6060/debug/pprof/ ,检查是否正常响应。
2.浏览器访问
访问 http://127.0.0.1:6060/debug/pprof/ ,页面如下:
allocs: 所有过去内存分配的样本
block: 导致同步阻塞的堆栈跟踪
cmdline: 当前程序的命令行调用
goroutine: 所有当前 goroutine 的堆栈跟踪
heap: 活动对象的内存分配情况。您可以指定 gc GET 参数以在获取堆样本之前运行 GC。
mutex: 争用互斥锁持有者的堆栈跟踪
profile: 默认进行 30s 的 CPU Profiling,得到一个分析用的 profile 文件。您可以在秒 GET 参数中指定持续时间。获取配置文件后,使用 go tool pprof 命令来调查配置文件。
threadcreate: 创建新操作系统线程的堆栈跟踪
trace: 当前程序的执行轨迹。您可以在秒 GET 参数中指定持续时间。获取跟踪文件后,使用 go tool trace 命令来调查跟踪。
3.可视化界面分析profile文件
1、文件下载
浏览器页面直接下载:http://127.0.0.1:6060/debug/pprof/
或者终端命令下载:wget http://127.0.0.1:6060/debug/pprof/profile
有时可能存在网络隔离问题,那也可以这么做:
curl http://localhost:6060/debug/pprof/heap?seconds=30 > heap.out
# 下载heap.out到本地
go tool pprof heap.out
2、文件分析
本地执行终端命令:该命令将在所指定的端口号运行一个 PProf 分析用的站点。
go tool pprof -http=:6001 profile文件
如果出现错误提示 Could not execute dot; may need to install graphviz.,那么意味着你需要安装 graphviz 组件。参考 安装Graphviz
3、文件内容
通过 PProf 所提供的可视化界面,我们能够更方便、更直观的看到 Go 应用程序的调用链、使用情况等。另外在 View 菜单栏中,PProf 还支持多种分析方式的切换,如下:
接下来我们将基于 CPU Profiling 所抓取的 Profile 进行一一介绍,而其它 Profile 类型的分析模式也是互通的,只要我们了解了一种,其余的也就会了。
Top
- flat:函数自身的运行耗时。
- flat%:函数自身在 CPU 运行耗时总比例。
- sum%:函数自身累积使用 CPU 总比例。
- cum:函数自身及其调用函数的运行总耗时。
- cum%:函数自身及其调用函数的运行耗时总比例。
- Name:函数名。
在大多数的情况下,我们可以通过这五列得出一个应用程序的运行情况,知道当前是什么函数,正在做什么事情,占用了多少资源,谁又是占用资源的大头,以此来得到一个初步的分析方向。
Graph
该视图展示的为整体的函数调用流程,框越大、线越粗、框颜色越鲜艳(红色)就代表它占用的时间越久,开销越大。相反若框颜色越淡,越小则代表在整体的函数调用流程中,它的开销是相对较小的。
因此我们可以用此视图去分析谁才是开销大头,它又是因为什么调用流程而被调用的。
Flame Graph
Flame Graph(火焰图)它是可动态的,调用顺序由上到下(A -> B -> C -> D),每一块代表一个函数、颜色越鲜艳(红)、区块越大代表占用 CPU 的时间更长。同时它也支持点击块深入进行分析,这样子我们就可以根据不同函数的多维度层级进行分析,能够更好的观察其流转并发现问题。
Flame Graph(new)
Peek
此视图相较于 Top 视图,增加了所属的上下文信息的展示,也就是函数的输出调用者/被调用者。
Source
该视图主要是增加了面向源代码的追踪和分析,可以看到其开销主要消耗在哪里。
安装Graphviz
1、安装Homebrew
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
官网地址:https://brew.sh/index.html
2、安装graphviz程序。
brew install graphviz
参考
https://golang2.eddycjy.com/posts/ch6/01-pprof-1/
Go程序内存泄露问题快速定位 - MySpace
pprof 性能分析 | Go 语言高性能编程 | 极客兔兔
https://www.cnblogs.com/jiujuan/p/14598141.html