写点什么

Go: 使用 pprof 收集样本数据

用户头像
陈思敏捷
关注
发布于: 2020 年 08 月 21 日
Go: 使用pprof收集样本数据

ℹ️ 本文基于 Go 1.13。



pprof是用于分析性能数据(例如CPU或内存分配)的工具。 对应用程序进行性能分析需要在运行时收集数据,以便稍后聚合它们并生成图形。 现在,让我们深入研究此数据收集的工作流程,并了解如何对其进行调整。



工作流

pprof以固定的时间间隔收集分析数据,该间隔由每秒的收集次数定义。 默认参数是100,这意味着pprof每秒将收集一百次数据,即每10毫秒一次。



可以通过调用StartCPUProfile来启动pprof:

func main() {
f, _ := os.Create(`cpu.prof`)
if err != nil {
log.Fatal(err)
}
pprof.StartCPUProfile(f)
defer pprof.StopCPUProfile()
...
}



此过程将在正在运行的线程上自动设置一个定时器(下图中的M表示),该定时器允许Go定期收集分析数据。 这是第一个图:





有关P,M,G表示形式的更多信息,建议您阅读之前的文章  “Go: Goroutine, 系统线程和CPU管理



pprof仅分析当前正在运行的线程。 当Go调度器调度goroutine在某线程上运行时,将实时跟踪该线程。 这是更新的图:





关于Go调度器的更多信息,我建议您阅读之前的文章“Go: g0, 特殊的goroutine



然后,分析数据将按每个定义的时间间隔定期转储到缓冲区:





数据实际上是由gsignal转储的,gsignal是一个处理传入信号的goroutine。实际上,定时器在每个时间间隔发出信号。



关于信号和gsignal的更多信息,我建议您阅读之前的文章“Go:gsignal,信号大师



基于信号

在每个线程上创建的定时器是由setitimer方法和时间间隔定时器ITIMER_PROF管理的。时间计数仅在进程运行时才会减少,这样就能确保分析数据的准确。



一旦达到时间间隔,定时器就会发出一个SIGPROF信号,该信号将被Go截获,并将分析数据转储到缓冲区。可以通过从运行时包中调用函数SetCPUProfileRate来配置分析频率。必须在启动分析器之前执行以下操作:



func main() {
f, err := os.Create(`cpu.prof`)
if err != nil {
log.Fatal(err)
}
runtime.SetCPUProfileRate(10)
pprof.StartCPUProfile(f)
defer pprof.StopCPUProfile()
...
}



配置分析频率只能定义一次,pprof在启动分析器时定义它。在启动分析器之前调用该方法将导致pprof忽略默认值。但是,在大多数情况下,默认值应该足够了。这个选择在软件包中有很好的解释:



100赫兹是一个合理的选择:可以产生足够多有用的数据,足够少影响系统稳定。

数据收集

定时器现在都设置好了。一旦缓冲,pprof需要一种方法来收集所有数据来创建报告。这个过程由一个单独的goroutine完成,该goroutine每隔100毫秒收集并格式化数据。



生成完成后,即分析停止后,专用goroutine会将报告转储到文件中,使其可用并完成可视化。



编译自:https://medium.com/a-journey-with-go/go-samples-collection-with-pprof-2a63c3e8a142



博客地址:

https://www.chenjie.info/2582

本文首发于我的公众号:



发布于: 2020 年 08 月 21 日阅读数: 62
用户头像

陈思敏捷

关注

多动脑不痴呆 2017.12.21 加入

gopher

评论

发布
暂无评论
Go: 使用pprof收集样本数据