前言
我们使用Go语言开发时难免遇到性能问题,内存泄漏、Goroutine卡死等。Go语言也自带PProf工具,为我们检测性能提供手段。
引入方式
PProf 可以从以下两个包中引入:
import "net/http/pprof"
import "runtime/pprof"
其中 net/http/pprof 使用 runtime/pprof 包来进行封装,并在 http 端口上暴露出来。runtime/pprof 可以用来产生 dump 文件,再使用 Go Tool PProf 来分析这运行日志。
使用 net/http/pprof 可以做到直接看到当前 web 服务的状态,包括 CPU 占用情况和内存使用情况等。
如果服务是一直运行的,如 web 应用,可以很方便的使用第一种方式 import "net/http/pprof",下面主要介绍通过 web 收集 prof 信息方式的使用。
使用案例
以go-pprof-practice为测试对象
环境 Go1.18
- 使用
go get -d github.com/wolfogre/go-pprof-practice下载代码至本地,使用-d避免自动安装 - 切换到项目目录下,使用
go build构建项目后运行 - pprof会自动注册 handler 到 http server,方便通过 http 接口获取程序运行采样报告
- 项目运行后打开浏览器访问
http://localhost:6060/debug/pprof/页面上展示了可用的程序运行采样数据:
分别代表意思如下:
| 类型 | 描述 | 备注 |
|---|---|---|
| allocs | 内存分配情况的采样信息 | 可以用浏览器打开,但可读性不高 |
| blocks | 阻塞操作情况的采样信息 | 可以用浏览器打开,但可读性不高 |
| cmdline | 显示程序启动命令及参数 | 可以用浏览器打开,这里会显示 ./go-pprof-practice |
| goroutine | 当前所有协程的堆栈信息 | 可以用浏览器打开,但可读性不高 |
| heap | 堆上内存使用情况的采样信息 | 可以用浏览器打开,但可读性不高 |
| mutex | 锁争用情况的采样信息 | 可以用浏览器打开,但可读性不高 |
| profile | CPU 占用情况的采样信息 | 浏览器打开会下载文件 |
| threadcreate | 系统线程创建情况的采样信息 | 可以用浏览器打开,但可读性不高 |
| trace | 程序运行跟踪信息 | 浏览器打开会下载文件 |
- 直接阅读采样信息缺乏直观性我们需要借助
go tool pprof命令来排查问题
排查CPU,我们在终端输入go tool pprof http://localhost:6060/debug/pprof/profile,等待一会儿后,进入一个交互式终端,输入 top 命令,查看 CPU 占用较高的调用,输入 list Eat,查看问题具体在代码的哪一个位置。我们可以输入web图形化显示调用栈信息,但是需要先安装graphviz,graphviz官网
排查内存,使用go tool pprof http://localhost:6060/debug/pprof/heap再一次使用 top、list 来定问问题代码
排除频繁GC,go tool pprof http://localhost:6060/debug/pprof/allocs,同样使用 top、list、web定位问题
排查协程泄露,go tool pprof http://localhost:6060/debug/pprof/goroutine
排查阻塞操作,go tool pprof http://localhost:6060/debug/pprof/block