上图中框出的这 4 个部分应该是平时最常用的,从上往下分别是:
虽然直接在浏览器页面上也能看到一些信息,但是用来分析是不够的,想要真正能分析问题还得通过前面提到的 pprof 工具。
使用 go tool pprof 分析数据,有两种方式:
- 通过url。go tool pprof http://localhost:8899/debug/pprof/profile
- 通过文件。go tool pprof cpuprofile 文件路径
好了,我们来试一下。
Z哥写了一段消耗内存的代码,如下:
func main() {
go func() {
http.ListenAndServe("0.0.0.0:8899", nil)
}()
str := "sadasdasffrgrgrgrgrgrfefafasfsadasdasffrgrgrgrgrgrfefafasfsadasdasffrgrgrgrgrgrfefafasfsadasdasffrgrgrgrgrgrfefafasfsadasdasffrgrgrgrgrgrfefafasfsadasdasffrgrgrgrgrgrfefafasf"
for i := 0; i < 999; i++ {
str += str
}
fmt.Scanln()
}
在 web 页面点击「heap」入口,我们可以看到实时内存的使用情况。
然后我们再通过以下命令进入到命令交互模式看看效果:
go tool pprof http://localhost:8899/debug/pprof/heap
进去之后输入「top」,就能很直观的看到哪个方法占用了内存。
这里的几个列的含义简单罗列下:
我们可以再输入获得更详细的信息:
list main.main
每一行代码占用了多少容量直接给你罗列出来了,是不是很香。
分析其他的也是类似的,比如以下是分析 CPU 的。
大多数时候,我们可能没有条件实时分析程序运行情况。比如问题在生产环境偶发出现,且无法在测试环境重现。
这个时候我们可以配置当程序 crash 的时候自动保存 dump 文件。
先输入命令「ulimit -a」看下当前是否开启了core file。
如果是0的话说明未开启。可以通过:
ulimit -c 1024 或者 ulimit -c unlimited 来设置 dump 文件的最大 size。
这里的数字单位是 block,具体需要根据所在的操作系统一个 block 对应的大小来设置。
如果你想让这个设置永久生效那么需要将它添加到 /.profile 中
echo "ulimit -c unlimited" >> ~/.profile
再看下 Golang 的环境变量 GOTRACEBACK 的设置是什么,
export
如果不是 crash 或者不存在 GOTRACEBACK 的环境变量(默认是 none)的话,改成 crash。
export GOBACTRACE=crash
这就意味着,让程序发生 crash 的时候会自动生成 dump 文件。(Z哥在 mac 系统上运行没能自动生成 dump 文件,但在 centos 上可以)
然后运行的程序如果发生 panic,会自动生成 dump 文件在程序运行的目录下。
红框圈出来的是它的默认文件名的格式。
同unlimited 一样,也需要让这个设置永久生效的话,需要添加到/.profile中
echo "export GOTRACEBACK=crash " >> ~/.profile
有了 dump 文件,你就可以用 gdb 或者 delve 工具来分析了(官方更建议我们使用 delve,对 Golang 的支持更好),这里就先不展开了。
一般来说,建议大家如果在本地环境的话使用 pprof 就好了,如果在服务器上,务必开始 crash 自动保存 dump 的功能,便于后续的快速定位问题并分析。
好了,这篇呢,Z 哥和你分享了在 Golang 中分析运行时的代码问题。主要有两种途径:
- 通过 pprof 实时分析。
- 程序 crash 时自动保存 dump,再通过 delve 或者 gdb 分析。
希望对你有所帮助。建议收藏,以防不备之需~
推荐阅读:
也可以「关注」我,带你以技术思维看世界~ 想更进一步和我一起玩耍,欢迎「搜索微信公号:跨界架构师」。