首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

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形式获取采样数据需要在主函数中添加以下代码:

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

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

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,然后会进入交互模式,直接就可以查看数据,如下:

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

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

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

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

debug/pprof/symbol

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

num_symbols: 10x4e667d io/ioutil.ReadAll0x6ec770 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进行数据分析,如下:

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

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

debug/pprof/

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

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

url后面有一个debug参数,其值可以为0、1或者其他预定的值,对以上5种类型的profile均起作用。debug分别代表以下含义:0,返回压缩后的原始格式的数据,其内容只包含pprof所需要的相关十六进制地址;1,返回内容会包含函数名、行号等信息,方便直接查看信息。除了以上两种情况外,某些类型的profile有其它预定的debug值,比如goroutine类型的profile,debug可以等于2。

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

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

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

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

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

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

上图中包含了堆分配的细节,同时在底部还包含了整个堆的统计信息、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

参考文档:

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

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

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

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180205G0ADOS00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券