应用程序在运行时,总是会出现一些你所意料不到的问题,像是跑着跑着突然报警,监控提示你进程 CPU 使用率过高、内存占用不断增大(疑似泄露)、临时内存大量申请后长时间内不滑,又或是 Goroutine 泄露、出现 Goroutine 数量暴涨,并且持续保持,甚至是莫名其妙在某次迭代发布后的数小时内出现了应用程序无法提供服务的问题…
这发生起来的话,是多么的让人感到担忧,那么除了在我们平时要做好各类防护以外,在问题正在发生时,我们又有什么办法排查呢,因此在这个章节,我们将介绍排查办法之一,也就是 Go 语言的性能剖析大杀器 PProf 工具链,它是 Go 语言中必知必会的技能点。
PProf 是什么
在 Go 语言中,PProf 是用于可视化和分析性能分析数据的工具,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 Profiling 这项功能会在实际排查中会经常用到。
因为很多问题出现时的表象就是 Goroutine 暴增,而这时候我们要做的事情之一就是查看应用程序中的 Goroutine 正在做什么事情,因为什么阻塞了,然后再进行下一步。