func init() {
   http.HandleFunc("/debug/pprof/", Index)
   http.HandleFunc("/debug/pprof/cmdline", Cmdline)
   http.HandleFunc("/debug/pprof/profile", Profile)
   http.HandleFunc("/debug/pprof/symbol", Symbol)
   http.HandleFunc("/debug/pprof/trace", Trace)
}

  

实际上,在初始化函数中, net/http/pprof 会对标准库中的 net/http 默认提供 DefaultServeMux 进行路由注册,源码如下
func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
   DefaultServeMux.HandleFunc(pattern, handler)
}
我们在例子中使用的 HTTP Server,也是标准库默认提供的,因此便可以注册进去。
在实际项目中 我们有独立的 ServeMux的,这时候只需要将PProf对应的路由注册进去即可  
mux := http.NewServeMux()
mux.HandleFunc("/debug/pprof",pprof.Index)
mux.HandleFunc("/debug/pprof/cmdline",pprof.cmdline)
mux.HandleFunc("/debug/pprof/profile", pprof.Profile)
mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
mux.HandleFunc("/debug/pprof/trace", pprof.Trace)

  

好了 我们运行了上面的程序后,浏览器直接访问:

如果在访问路径上加上 ?debug=1 则可以直接在浏览器中访问。
这个页面中有许多子页面,咱们继续深究下去,看看可以得到什么?
  • profile(CPU Profiling): $HOST/debug/pprof/profile,默认进行 30s 的 CPU Profiling,得到一个分析用的 profile 文件
  • allocs 查看过去所有内存分配样本,访问路径为 /debug/pprof/allocs
  • cmdline 当前程序命令行的完整调用路径
  • block(Block Profiling):$HOST/debug/pprof/block,查看导致阻塞同步的堆栈跟踪
  • goroutine:$HOST/debug/pprof/goroutine,查看当前所有运行的 goroutines 堆栈跟踪
  • heap(Memory Profiling): $HOST/debug/pprof/heap,查看活动对象的内存分配情况
  • mutex(Mutex Profiling):$HOST/debug/pprof/mutex,查看导致互斥锁的竞争持有者的堆栈跟踪
  • threadcreate:$HOST/debug/pprof/threadcreate,查看创建新OS线程的堆栈跟踪
一般在线上环境,为了网络安全,通常不会这么做。另外debug的访问方式是具有时效性的,在实际场景中,我们常常需要及时将当前状态下的 profile文件给存储下来,便于二次分析。
 

通过终端访问

第二种是通过命令行完整对正在运行的程序 pprof进行抓取和分析