不能在现有服务器上使用 go tool pprof
Can't use go tool pprof with an existing server
我有一个现有的 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 page not found
。
这就是我在本地机器上使用 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
看起来问题出在 github.com/gorilla/mux
中使用的 *mux.Router
,我在 http.Server
实例中将其用作 Handler
。
解决方案:只为 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())
文档中没有明确提及,但 net/http/pprof
仅向 http.DefaultServeMux
注册了它的处理程序。
来自source:
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))
}
如果您不使用默认的多路复用器,则只需使用您正在使用的任何多路复用器注册 any/all 个您想要的多路复用器,例如像 mymux.HandleFunc("…", pprof.Index)
,等等
或者,您可以在一个单独的端口上监听(如果需要,也可以只绑定到本地主机),默认多路复用器为 。
如果您使用的是 github.com/gorilla/mux.Router
,您可以简单地将任何以 /debug/
为前缀的请求传递给 http.DefaultServeMux
。
import _ "net/http/debug"
router := mux.NewRouter()
router.PathPrefix("/debug/").Handler(http.DefaultServeMux)
以下是如何将 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
我有一个现有的 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 page not found
。
这就是我在本地机器上使用 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
看起来问题出在 github.com/gorilla/mux
中使用的 *mux.Router
,我在 http.Server
实例中将其用作 Handler
。
解决方案:只为 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())
文档中没有明确提及,但 net/http/pprof
仅向 http.DefaultServeMux
注册了它的处理程序。
来自source:
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))
}
如果您不使用默认的多路复用器,则只需使用您正在使用的任何多路复用器注册 any/all 个您想要的多路复用器,例如像 mymux.HandleFunc("…", pprof.Index)
,等等
或者,您可以在一个单独的端口上监听(如果需要,也可以只绑定到本地主机),默认多路复用器为
如果您使用的是 github.com/gorilla/mux.Router
,您可以简单地将任何以 /debug/
为前缀的请求传递给 http.DefaultServeMux
。
import _ "net/http/debug"
router := mux.NewRouter()
router.PathPrefix("/debug/").Handler(http.DefaultServeMux)
以下是如何将 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