Golang pprof解读

Posted 太合音乐技术团队

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Golang pprof解读相关的知识,希望对你有一定的参考价值。


导读:在使用golang进行开发过程中,经常需要对程序进行性能分析和优化,pprof是首选工具。在使用过程中,pprof有多个入口,同时也提供了多维度的执行数据,到底我们该如何去使用这个工具,下面我们来一起学习。


golang在语言层面集成了profile采样工具,在程序运行过程中可以获取cpu、heap、block、traces等执行信息,这些会涉及到runtime/pprof、net/http/pprof、runtime/trace等package。本文中所讲内容均基于go 1.9.2版本。

一般情况下,获取profile数据最有两种形式:web形式与profile文件生成形式。


web形式

通过web形式获取采样数据需要在主函数中添加以下代码:

Golang pprof解读

net/http/pprof包的init函数中注册了以下路由到http服务中:

Golang pprof解读

下面分别说明各个路由对应服务的功能:

  • debug/pprof/cmdline

这个接口功能很简单,主要是调用os.Args,获取程序启动时的命令及参数。访问http://ip:port/debug/pprof/cmdline 即可获取结果。


  • debug/pprof/profile

此接口返回CPU的profile,调用了runtime/pprof包的StartCPUProfile,采样频率为100Hz。接口默认是返回30秒的数据,可以通过seconds参数设定需要获取的数据时长。比如获取10秒钟的cpu profile数据,有两种方式进行数据获取与分析:

1. go tool pprof http://ip:port/debug/pprof/profile?seconds=10,然后会进入交互模式,直接就可以查看数据,如下:

Golang pprof解读


2. 先获取profile文件,然后使用go tool pprof进行分析。

wget http://localhost:8080/debug/pprof/profile?seconds=10 -O testfile

然后进行分析:go tool pprof testfile, 如下:

Golang pprof解读

其实第一种方式只是把获取文件和交互操作模式放到一起执行而已,profile数据已经被保存到了/tmp目录下。


  • debug/pprof/symbol

根据传入的程序计数器(PC)的值,获取对应的函数的名称信息,调用了runtime包的FuncForPC获取对应的函数信息。可以传入多个PC值,以加号作为连接符号,比如访问:http://ip:port/debug/pprof/symbol?0x4e667d+0x6ec770 (PC值当然是每个程序运行都不一样,这里只是个示例),返回PC值与函数对应名称的信息,如下:


num_symbols: 1 0x4e667d io/ioutil.ReadAll 0x6ec770 main.httpGet


  • debug/pprof/trace

此接口用于获取程序执行中的事件跟踪信息,比如协程、系统调用、GC、堆大小改变等事件,大多数事件的跟踪精确度能达到纳秒级别,后端调用了runtime包的StartTrace,会进行一个STW的操作。获取数据的时长默认为1秒,可以通过seconds参数进行修改。先通过以下命令获取数据:

wget http://ip:port/debug/pprof/trace?seconds=10 -O tracefile

然后执行go tool trace tacefile进行数据分析,如下:

Golang pprof解读


进入View trace可以看到如下信息:

Golang pprof解读

以此可以对执行信息进行深入分析。


  • debug/pprof/

如果访问此路径时,不包含子路径,返回所有可用类型的profile列表,访问http:/ip:port/debug/pprof,如下:

Golang pprof解读


如果包含子路径,可用获取对应如下子路径对应的详细profile信息:

Golang pprof解读


下面来看上面五种profile的信息:

  • block:报告协程阻塞的情况,可以用来分析和查找死锁等性能瓶颈,默认不开启, 需要调用runtime.SetBlockProfileRate开启。下面看个例子,访问http://ip:port/debug/pprof/block?debug=1,其展示结果如下:

Golang pprof解读

可以看出图中的阻塞都发生在网络等待上。还可以通过go tool pprof http://ip:port/debug/pprof/block进入交互模式进行查看。


  • goroutine:报告协程相关信息,可以用来查看有哪些协程正在运行、有多少协程在运行等。访问http://ip:port/debug/pprof/goroutine?debug=1,如下:

Golang pprof解读

可以看出图中的大量协程都和网络传输有关系。


  • heap:查看堆相关信息,包括一些GC的信息。访问http://ip:port/debug/pprof/heap?debug=1

Golang pprof解读

上图中包含了堆分配的细节,同时在底部还包含了整个堆的统计信息、GC的统计信息等。同样,也可以使用go tool pprof http://ip:port/debug/pprof/heap进入交互模式进行查看。可以指定以下4个选项,alloc_objects、alloc_space、inuse_objects、inuse_space默认为alloc_space。


  • mutex: 查看互斥的争用情况,默认不开启, 需要调用需要在程序中调用runtime.SetMutexProfileFraction。


  • threadcreate:查看线程创建信息



文件生成形式

通过生成profile文件的形式来获取数据,需要在代码中添加如下代码。

然后使用go tool分析文件。或者使用test的功能获取profile文件:go test -cpuprofile cpu.prof -memprofile mem.prof -bench .


当然,除了以上3种形式,用户也可以在程序直接调用runtime中的功能进行profile数据获取,runtime包中提供了相关的接口。如果想进行更深入的研究,可以查看https://blog.golang.org/2011/06/profiling-go-programs.html


参考文档:

  1.  https://golang.org/pkg/net/http/pprof/

  2.  https://blog.golang.org/profiling-go-programs

  3. https://github.com/golang/go/wiki/Performance

                              



    


以上是关于Golang pprof解读的主要内容,如果未能解决你的问题,请参考以下文章

Golang pprof详解

golang: 使用pprof做性能分析

golang: 使用pprof做性能分析

golang 性能测试pprof

Golang 大杀器之性能剖析 PProf

golang pprof 性能分析工具