摘抄:golang pprof实用使用指南
注册接口
第一步,在引用中加上
1 2
| "net/http" _ "net/http/pprof"
|
第二步,在代码开始运行的地方加上
1 2 3
| go func() { log.Println(http.ListenAndServe(":6060", nil)) }()
|
接着,我们访问http://127.0.0.1:6060/debug/pprof/,即可看到

- allocs:查看过去所有内存分配的样本。
- block:查看导致阻塞同步的堆栈跟踪。
- cmdline: 当前程序的命令行的完整调用路径。
- goroutine:查看当前所有运行的 goroutines 堆栈跟踪。
- heap:查看活动对象的内存分配情况。
- mutex:查看导致互斥锁的竞争持有者的堆栈跟踪。
- profile: 默认进行 30s 的 CPU Profiling,得到一个分析用的 profile 文件。
- threadcreate:查看创建新 OS 线程的堆栈跟踪。
- trace:mp.weixin.qq.com/s/I9xSMxy32…
注意,默认情况下是不追踪block和mutex的信息的,如果想要看这两个信息,需要在代码中加上两行:
1 2
| runtime.SetBlockProfileRate(1) runtime.SetMutexProfileFraction(1)
|
注意,上文的所有信息都是实时的,如果你刷新一下,是可以看到数字在变化的。此时如果点击蓝色的连接,可以看到一些协程的栈信息,这些信息并不容易阅读。如果想要更加清晰的数据,需要将信息保存下来,在本地进行分析。
给服务都注册上没问题,但是最好还是加个中间件控制一下访问
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| package main
import ( "net/http" "net/http/pprof"
"github.com/gin-gonic/gin" )
const ( AllowPprof = true )
func AccessControl(c *gin.Context) { if AllowPprof { c.Next() return } c.Next() }
func main() { bizApp := gin.Default()
bizApp.GET("/", func(c *gin.Context) { c.JSON(200, gin.H{ "message": "Hello, World!", }) })
pprofApp := gin.Default() pprofApp.Use(AccessControl) pprofApp.GET("/debug/pprof/", gin.WrapH(http.HandlerFunc(pprof.Index))) pprofApp.GET("/debug/pprof/allocs", gin.WrapH(pprof.Handler("allocs"))) pprofApp.GET("/debug/pprof/block", gin.WrapH(pprof.Handler("block"))) pprofApp.GET("/debug/pprof/goroutine", gin.WrapH(pprof.Handler("goroutine"))) pprofApp.GET("/debug/pprof/heap", gin.WrapH(pprof.Handler("heap"))) pprofApp.GET("/debug/pprof/mutex", gin.WrapH(pprof.Handler("mutex"))) pprofApp.GET("/debug/pprof/threadcreate", gin.WrapH(pprof.Handler("threadcreate"))) pprofApp.GET("/debug/pprof/cmdline", gin.WrapH(http.HandlerFunc(pprof.Cmdline))) pprofApp.GET("/debug/pprof/profile", gin.WrapH(http.HandlerFunc(pprof.Profile))) pprofApp.GET("/debug/pprof/symbol", gin.WrapH(http.HandlerFunc(pprof.Symbol))) pprofApp.GET("/debug/pprof/trace", gin.WrapH(http.HandlerFunc(pprof.Trace))) go func() { pprofApp.Run(":8081") }()
bizApp.Run(":8080") }
|
采集&分析数据
有两种方式下载信息
方法一(推荐):
直接运行go tool pprof http://localhost:6060/debug/pprof/XXX,其会自动下载数据到本地,然后供你分析。
实践:
1 2 3 4 5 6 7 8
| ❯ go tool pprof http://10.251.179.31:9202/debug/pprof/heap Fetching profile over HTTP from http://10.251.179.31:9202/debug/pprof/heap Saved profile in /Users/g****ng/pprof/pprof.logic_core.alloc_objects.alloc_space.inuse_objects.inuse_space.001.pb.gz File: logic_core Type: inuse_space Time: 2025-08-28 22:07:21 CST Entering interactive mode (type "help" for commands, "o" for options) (pprof)
|
方法二:
访问http://localhost:6060/debug/pprof/xxx,浏览器就会提醒你下载文件。
这里有一个小点要注意,在这个页面下,点击profile和trace总是会下载文件。而点击其他链接会跳转到另一个页面,来展示一些数据,但是可读性也比较差。
如果点击profile,程序会开始进行半分钟(默认值)的CPU采样,然后才会下载文件。

在跳转到页面中,会发现URL带有?debug=1的后缀,如果把这个后缀去掉,则也会提示你下载文件。
1
| curl http://localhost:9591/debug/pprof/goroutine -o goroutine-pprof
|
1
| go tool pprof -http=:8000 cpu.pprof
|
注意事项
OOM
当发生OOM的时候,拉取到heap文件后渲染,需要设置一下采样范围为"已分配",而不是"inused"
