利用pprof进行性能分析
pprof性能分析的5个方面
一、性能分析的五个核心维度
-
CPU分析 - 剖析程序的CPU使用情况,定位高耗时函数
-
内存分析 - 追踪内存分配与泄露,优化内存使用模式
-
IO分析 - 监控文件/网络IO操作,发现瓶颈资源
-
Goroutine分析 - 检测协程泄露与异常堆栈
-
并发问题分析 - 诊断死锁及通过race detector检测数据竞争
数据采集时间
生产环境采集:选择业务低峰期进行采样(凌晨2-4点)
测试环境采集:模拟真实负载场景进行压力测试
黄金准则:采样时长控制在30-60秒,确保覆盖完整业务周期
pprof集成方案
1、方案1:HTTP服务集成(推荐)
import ("net/http",_ "net/http/pprof"
)func main(){go func(){if err:=http.ListenAndServer(addr:"6060",handler:nil);err!=nil{log.Fatal(err)}os.Exit(code:0)}()
}
可以加入runtime,开启对锁调用的跟踪。
import ("runtime"
)func main(){runtime.SetMutexProfileFraction(rate:1) //开启对锁的跟踪runtime.SetBlockProfileRate(rate:1) //开启对阻塞的跟踪go func(){if err:=http.ListenAndServer(addr:"6060",handler:nil);err!=nil{log.Fatal(err)}os.Exit(code:0)}()
}
有聪明的小伙伴可能会问“持续性采样,会不会影响服务器性能啊”。其实不会,pprof服务会按需采样,大部分端点只在请求时生成数据持续监控。只有runtime统计信息(如goroutine数量)会实时更新,因此只要控制好你的请求频率,不会对生成开发过程造成很大影响。
2、通过基准测试采集数据
func BenchmarkMyFunc(b *testing.B) {// 测试逻辑...
}
执行命令采集数据go test -bench=. -cpuprofile=cpu.out
诊断端点详解
针对第一种HTTP服务集成,访问 http://localhost:6060/debug/pprof/ 获取以下分析入口:
分析类型 | 描述 | 启用方式 |
---|---|---|
allocs | 跟踪所有内存分配情况(包括已释放的内存) | 默认启用 |
block | 分析阻塞操作(如 channel 阻塞、锁等待) | 需调用 SetBlockProfileRate |
cmdline | 显示程序启动时的命令行参数 | 默认启用 |
goroutine | 统计当前所有 goroutine 的堆栈跟踪信息 | 默认启用 |
heap | 分析当前活跃的堆内存分配(与 allocs 不同,仅包含未释放的内存) | 默认启用 |
mutex | 跟踪锁竞争情况(如 sync.Mutex 的争用) | 需调用 SetMutexProfileFraction |
profile | 采集 CPU 使用数据,支持 seconds 参数(默认 30 秒) | 默认启用 |
threadcreate | 跟踪操作系统线程创建情况(常用于检测 goroutine 泄漏) | 默认启用 |
我们发现,在http://localhost:6060/debug/pprof/
中的文件可读性非常差,实际上它只是作为一个数据源。我们可以通过性能分析工具对其文件进行分析。golang中有自带的go tool pprof
工具。
可以直接将文件下载下来对文件进行分析,也可以直接使用文件的url。
如果要导出图片或者pdf等文件,需要下载 graphviz。大家想的话,可以自己搜索下载。
可视化分析
可以使用 go tool pprof +source (source可以是可执行文件,也可以是网址。)
例如 go tool pprof http://localhost:6060/debug/pprof/allocs
可以在命令行中分析程序内存使用情况。
go tool pprof http://localhost:6060/debug/pprof/profile?seconds=30
可以分析CPU使用情况。(采集30秒)
运行过上述命令后,即进入命令行终端。可以通过help
查看支持的指令。
我们介绍几个常用的:top
,list
,web
。
top命令 显示资源消耗TOP N函数
最常用的top
,查看使用的数据,默认取前10条,可以使用top 5
,可以查看消耗资源(内存,协程数,cpu用的最多的等等)最多的5个。其中的指标有:
指标 | 全称 | 技术定义 |
---|---|---|
flat | Exclusive Time | 函数自身直接消耗的CPU时间/内存量(不包含子调用) |
flat% | Exclusive Percentage | 当前函数独占资源占总采样资源的百分比 |
cum | Cumulative Time | 函数及其调用链消耗的总资源(包含所有子调用) |
cum% | Cumulative Percentage | 函数调用链资源消耗占总采样资源的百分比 |
sum% | Aggregated Percentage | 当前函数及其之前函数资源消耗的累计占比(TOP列表特有指标) |
list命令 源码级函数分析
通过list
可以展开源代码,list + 某个interface,或者函数
,会列出其所有interface
对应的方法,或所有函数实现的源代码。可以结合top一起使用,查看消耗资源最多的出现在
web生成可视化图形
通过 web
可以打开分析的连线图。
图中,有很多长方形,框框越大,代表消耗的资源越多。线约粗,整个调用栈消耗的资源越多。
每个方格中第一行,代表包名。
第二行,对象名。
第三行代表方法名。
第四行,flat(flat%)。
第五行,cum(cum%)。
图形化分析
通过 go tool pprof 的 Web 交互模式,可以将远程 pprof 数据本地可视化,实现命令行功能的图形化操作。具体流程如下:
go tool pprof -http=:8000 http://localhost:6060/debug/pprof/goroutine
功能模块 | 对应命令行操作 | 核心作用 | 交互优势 |
---|---|---|---|
Top | top | 展示资源消耗 Top N 的函数(按 CPU/内存/锁等指标排序) | 动态排序 + 百分比占比可视化 |
Graph | web | 生成函数调用关系拓扑图(需 Graphviz) | 链路依赖关系一目了然 |
Flame Graph | 无直接对应命令 | 通过火焰图直观定位性能瓶颈(层级宽度=资源消耗量) | 快速识别热点代码路径 |
Peek | peek <function> | 聚焦特定函数及其上下游调用链 | 无需记忆命令,点击交互 |
Source | list <function> | 源码级资源消耗分析(显示每行代码的资源开销) | 直接关联业务代码 |
Compare | diff_base | 对比两个 Profile 文件的差异(常用于优化前后效果验证) | 差异高亮 + 变化量统计 |
关键特性说明:
-
本地化分析
工具可以将远程 pprof 数据下载到本地(存储于 ~/pprof 目录)进行分析,避免对生产服务造成性能影响。
-
协议兼容性
支持 HTTP/HTTPS 协议拉取数据,适用于 Kubernetes 等容器环境。
例如go tool pprof -http=:8000 https://k8s-cluster:443/debug/pprof/profile
-
原生指令支持
网页顶部提供命令行输入框,可直接执行 top -cum 等高级参数指令,实现精准过滤。