无法使用go tool pprof来分析已存在的服务器

20

我有一个现有的HTTP服务器,我想对其进行性能分析。我已经把"net/http/pprof"导入到我的代码中,并且已经运行了HTTP服务器:

router := createRouter()
server := &http.Server {
    Addr:           ":8080",
    Handler:        router,
    ReadTimeout:    15*time.Second,
    WriteTimeout:   15*time.Second,
//  MaxHeaderBytes: 4096,
}

log.Fatal(server.ListenAndServe())
当我尝试访问http://localhost:8080/debug/pprof/时,我收到了404页面未找到的错误信息。
在本地机器上使用go tool pprof时,我会得到以上内容。
userver@userver:~/Desktop/gotest$ go tool pprof http://192.168.0.27:8080/
Use of uninitialized value $prefix in concatenation (.) or string at /usr/lib/go/pkg/tool/linux_amd64/pprof line 3019.
Read http://192.168.0.27:8080/pprof/symbol
Failed to get the number of symbols from http://192.168.0.27:8080/pprof/symbol

userver@userver:~/Desktop/gotest$ go tool pprof http://localhost:8080/debug/pprof/profile
Read http://localhost:8080/debug/pprof/symbol
Failed to get the number of symbols from http://localhost:8080/debug/pprof/symbol

对于远程客户端同样适用:

MacBookAir:~ apple$ go tool pprof http://192.168.0.27:8080/
Use of uninitialized value $prefix in concatenation (.) or string at /usr/local/Cellar/go/1.3.2/libexec/pkg/tool/darwin_amd64/pprof line 3027.
Read http://192.168.0.27:8080/pprof/symbol
Failed to get the number of symbols from http://192.168.0.27:8080/pprof/symbol
4个回答

29

虽然文档中没有明确提到,但net/http/pprof只注册其处理程序到http.DefaultServeMux

源代码可以看出:

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

如果您没有使用默认的mux,您只需在使用的任何mux中注册您想要的任何/全部mux,例如像mymux.HandleFunc("…", pprof.Index)等。

或者,您可以使用默认mux在单独的端口上侦听(如果需要,也可能仅绑定到localhost),如所示


2
我有一个问题:一旦进入/debug/pprof/,就会有几个链接导致404页面。特别是heapallocs 404。正如你上面展示的那样,我没有看到这些路径的路由在net/http/pprof/pprof.goinit()函数中提供。我该如何使它们可访问?您是否知道我如何联系@Dave C以获取这些信息? - Andrew B
如果您使用 router.PathPrefix("/debug/").Handler(http.DefaultServeMux),则会添加堆端点。如果应用 init 处理程序,则不会添加。不确定为什么... - andig
请注意,在使用Gorilla mux时,有一个警告 - 请参见下面的我的答案,以获取解决404错误的方法。 - rustyx

16
如果您正在使用github.com/gorilla/mux.Router,您可以将任何以/debug/为前缀的请求简单地移交给http.DefaultServeMux
import _ "net/http/debug"
router := mux.NewRouter()
router.PathPrefix("/debug/").Handler(http.DefaultServeMux)

14

看起来问题出在我在我的http.Server实例中作为Handler使用的来自github.com/gorilla/mux*mux.Router

解决方案:再启动一个服务器专门用于pprof

server := &http.Server {
    Addr:           ":8080",
    Handler:        router,
    ReadTimeout:    15*time.Second,
    WriteTimeout:   15*time.Second,
}
go func() {
    log.Println(http.ListenAndServe(":6060", nil))
}()
log.Fatal(server.ListenAndServe())

3

以下是如何将pprof与Gorilla mux结合使用。为了避免HTTP 404错误,我们需要显式指定/debug/pprof/{cmd}路由,因为Gorilla不进行前缀路由:

router := mux.NewRouter()
router.Handle("/debug/pprof/", http.HandlerFunc(pprof.Index))
router.Handle("/debug/pprof/cmdline", http.HandlerFunc(pprof.Cmdline))
router.Handle("/debug/pprof/profile", http.HandlerFunc(pprof.Profile))
router.Handle("/debug/pprof/symbol", http.HandlerFunc(pprof.Symbol))
router.Handle("/debug/pprof/trace", http.HandlerFunc(pprof.Trace))
router.Handle("/debug/pprof/{cmd}", http.HandlerFunc(pprof.Index)) // special handling for Gorilla mux

err := http.ListenAndServe("127.0.0.1:9999", router)
log.Errorf("pprof server listen failed: %v", err) // note: http.ListenAndServe never returns nil

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接