飙血推荐
  • HTML教程
  • MySQL教程
  • JavaScript基础教程
  • php入门教程
  • JavaScript正则表达式运用
  • Excel函数教程
  • UEditor使用文档
  • AngularJS教程
  • ThinkPHP5.0教程

golang pprof

时间:2021-12-16  作者:yaohong  

一:背景

当正在运行的golang程序消耗预期之外的内存时间,我们这个时候就需要去弄明白,到底是是我们的代码哪个地方消耗了这些内存及相应时间。但此时编译好的golang程序对我们而言是黑盒,如果去分析具体的内存及时间使用情况?这个时候我们可以去了解和使用pprof来分析golang进程的内存使用。

二:实战

2.1.环境搭建

下载安装golang,需要进到pod容器中(或者也可以将这些打到基础镜像中)

$ wget https://域名/dl/域名.linux-域名    
$ tar -C /usr/local -xzf 域名x-域名
# 添加到环境变量中
$ export PATH=$PATH:/usr/local/go/bin


安装生成svg图的依赖

$ yum install graphviz -y


2.2.修改和添加业务代码

在相关业务服务代码main中添加以下代码

// pprof 的init函数会将pprof里的一些handler注册到域名ultServeMux上
// 当不使用域名ultServeMux来提供http api时,可以查阅其init函数,自己注册handler
import _ "net/http/pprof"

go func() {
    域名enAndServe("0.0.0.0:9090", nil)
}()

修改完成后编译二进制,并运行对应二进制。 

2.3.通过 Web 界面查看

查看当前总览:访问 http://127.0.0.1:9090/debug/pprof/,可以查看到如下图相关信息。

可以直接点击上面的链接,进入子页面,查看相关的汇总信息。

2.4.go tool分析法

2.4.1.内存分析

我们可以采用go tool pprof -inuse_space http://127.0.0.1:9090/debug/pprof/heap命令连接到进程中 查看正在使用的一些内存相关信息,此时我们得到一个可以交互的命令行。

我们可以看数据top10来查看正在使用的对象较多的10个函数入口。通常用来检测有没有不符合预期的内存 对象引用。

# go tool pprof -inuse_space http://127.0.0.1:9090/debug/pprof/heap
Fetching profile over HTTP from http://127.0.0.1:9090/debug/pprof/heap
Saved profile in /root/pprof/域名域名域名.域名
File: test_exporter
Type: inuse_space
Time: Dec 15, 2021 at 1:05pm (CST)
Entering interactive mode (type "help" for commands, "o" for options)
(pprof) top10
Showing nodes accounting for 域名, 100% of 域名 total
Showing top 10 nodes out of 12
      flat  flat%   sum%        cum   cum%
  域名   100%   100%   域名   100%  crypto/域名eCertificate
         0     0%   100%   域名   100%  crypto/x509.(*CertPool).AppendCertsFromPEM
         0     0%   100%   域名   100%  crypto/域名eCertificate
         0     0%   100%   域名   100%  crypto/域名emCertPool
         0     0%   100%   域名   100%  crypto/域名SystemRoots
         0     0%   100%   域名   100%  crypto/域名SystemRoots
         0     0%   100%   域名   100%  crypto/域名emRootsPool (inline)
         0     0%   100%   域名   100%  harbor_exporter/域名
         0     0%   100%   域名   100%  域名
         0     0%   100%   域名   100%  域名
(pprof) 

然后我们在用go tool pprof -alloc_space http://127.0.0.1:9090/debug/pprof/heap命令链接程序来查看 内存对象分配的相关情况。然后输入top来查看累积分配内存较多的一些函数调用:

# go tool pprof -alloc_space http://127.0.0.1:9090/debug/pprof/heap
Fetching profile over HTTP from http://127.0.0.1:9090/debug/pprof/heap
Saved profile in /root/pprof/域名域名域名.域名
File: test_exporter
Type: alloc_space
Time: Dec 15, 2021 at 1:08pm (CST)
Entering interactive mode (type "help" for commands, "o" for options)
(pprof) top
Showing nodes accounting for 域名, 域名% of 域名 total
Showing top 10 nodes out of 95
      flat  flat%   sum%        cum   cum%
 域名 域名% 域名%  域名 域名%  os.(*File).readdirnames
 域名 域名% 域名%  域名 域名%  compress/域名riter
 域名 域名% 域名%  域名 域名%  域名Slice
 域名 域名% 域名%  域名 域名%  域名link
 域名  域名% 域名%  域名  域名%  strings.(*Builder).grow (inline)
 域名  域名% 域名%  域名  域名%  runtime/域名tCPUProfile
 域名  域名% 域名%  域名  域名%  域名eaderSize (inline)
 域名  域名% 域名%  域名  域名%  域名SliceFromString
 域名  域名% 域名%  域名 域名%  域名/shirou/gopsutil/internal/域名LinesOffsetN
     515kB  域名% 域名%      515kB  域名%  crypto/x509.(*CertPool).AddCert
(pprof) 

我们可以根据如上内存分配情况去review代码,如何减少这些相关的调用,或者优化相关代码逻辑。

当我们不明确这些调用时是被哪些函数引起的时,我们可以输入top -cum来查找,-cum的意思就是,将函数调用关系 中的数据进行累积,比如A函数调用的B函数,则B函数中的内存分配量也会累积到A上面,这样就可以很容易的找出调用链。

(pprof) top20 -cum
Showing nodes accounting for 域名, 域名% of 域名 total
Showing top 20 nodes out of 95
      flat  flat%   sum%        cum   cum%
         0     0%     0% 域名 域名%  harbor_exporter/collector.(*Exporter).域名1
         0     0%     0% 域名 域名%  harbor_exporter/域名pe
         0     0%     0% 域名 域名%  域名/shirou/gopsutil/process.(*Process).OpenFiles (inline)
         0     0%     0% 域名 域名%  域名/shirou/gopsutil/process.(*Process).OpenFilesWithContext
         0     0%     0% 域名 域名%  域名/shirou/gopsutil/process.(*Process).fillFromfdWithContext
         0     0%     0%  域名 域名%  域名/shirou/gopsutil/process.(*Process).fillFromfdListWithContext
         0     0%     0%  域名 域名%  os.(*File).Readdirnames (inline)
 域名 域名% 域名%  域名 域名%  os.(*File).readdirnames
         0     0% 域名%  域名 域名%  域名/shirou/gopsutil/process.(*Process).CreateTimeWithContext
         0     0% 域名%  域名 域名%  域名/shirou/gopsutil/process.(*Process).createTimeWithContext
         0     0% 域名%  域名 域名%  域名/shirou/gopsutil/process.(*Process).fillFromStatWithContext
  域名  域名% 域名%  域名 域名%  域名/shirou/gopsutil/process.(*Process).fillFromTIDStatWithContext
         0     0% 域名%  域名 域名%  域名/shirou/gopsutil/域名rocessWithContext
         0     0% 域名%  域名 域名%  域名/shirou/gopsutil/域名esses (inline)
         0     0% 域名%  域名 域名%  域名/shirou/gopsutil/域名essesWithContext
         0     0% 域名%  域名 域名%  域名/shirou/gopsutil/internal/域名TimeWithContext
         0     0% 域名%  域名 域名%  域名/shirou/gopsutil/internal/域名Lines (inline)
 域名  域名% 域名%  域名 域名%  域名/shirou/gopsutil/internal/域名LinesOffsetN
 域名 域名% 域名%  域名 域名%  域名link
         0     0% 域名%  域名 域名%  net/http.(*ServeMux).ServeHTTP

2.域名耗时分析

我们可以采用go tool pprof http://127.0.0.1:9090/debug/pprof/profile命令连接到进程中 查看正在使用的一些CPU相关信息。

Type: cpu
Time: Dec 15, 2021 at 2:17pm (CST)
Duration: 30s, Total samples = 10ms (域名%)
Entering interactive mode (type "help" for commands, "o" for options)
(pprof) top 10
Showing nodes accounting for 10ms, 100% of 10ms total
      flat  flat%   sum%        cum   cum%
      10ms   100%   100%       10ms   100%  域名grab
         0     0%   100%       10ms   100%  域名runnable
         0     0%   100%       10ms   100%  域名l
         0     0%   100%       10ms   100%  域名_m
         0     0%   100%       10ms   100%  域名steal
         0     0%   100%       10ms   100%  域名dule
(pprof) 
(pprof) top20 -cum
Showing nodes accounting for 10ms, 100% of 10ms total
      flat  flat%   sum%        cum   cum%
         0     0%     0%       10ms   100%  域名runnable
         0     0%     0%       10ms   100%  域名l
         0     0%     0%       10ms   100%  域名_m
      10ms   100%   100%       10ms   100%  域名grab
         0     0%   100%       10ms   100%  域名steal
         0     0%   100%       10ms   100%  域名dule

2.3.3.获取svg图

在我们执行go tool pprof -inuse_space http://127.0.0.1:9090/debug/pprof/heap命令和go tool pprof http://127.0.0.1:9090/debug/pprof/profile命令都可以在回显中注入svg,这样将会产生一个.svg图片,其会把这些累积关系画成一个拓扑图,提供给 我们。

下面我们取一个图片中的一个片段进行分析:

pprof web

每一个方块为pprof记录的一个函数调用栈,连线上的标签代表指定的方法调用的采样值(例如时间、内存分配大小等),方框的大小与方法运行的采样值的大小有关。

每个方框由两个标签组成:在 cpu profile 中,一个是方法运行的时间占比,一个是它在采样的堆栈中出现的时间占比(前者是 flat 时间,后者则是 cumulate 时间占比);框越大,代表耗时越多或是内存分配越多。

--inuse/alloc_space --inuse/alloc_objects区别

通常情况下:

1.--inuse_space:用来分析程序常驻内存的占用情况;
2.--alloc_objects:用来分析内存的临时分配情况,可以提高程序的运行速度。

 原文:https://域名/yaohong/

标签:编程
湘ICP备14001474号-3  投诉建议:234161800@qq.com   部分内容来源于网络,如有侵权,请联系删除。