我有一个用Go编写的相对较大的Web应用程序,它使用Gorilla's mux进行路由。我最近意识到我的Web应用程序非常慢,我想对Web应用程序进行分析。
阅读之后,net/http/pprof似乎就是我所需要的。但我无法使用 mux 运行它;即使是最琐碎的Web应用程序。
有谁知道如何做到这一点?
以下是一个不起作用的简单代码示例(即/debug
没有提供任何内容)。
package main
import (
"fmt"
"github.com/gorilla/mux"
"math"
"net/http"
)
import _ "net/http/pprof"
func SayHello(w http.ResponseWriter, r *http.Request) {
for i := 0; i < 1000000; i++ {
math.Pow(36, 89)
}
fmt.Fprint(w, "Hello!")
}
func main() {
r := mux.NewRouter()
r.HandleFunc("/hello", SayHello)
http.ListenAndServe(":6060", r)
}
答案 0 :(得分:20)
user983716 - 感谢您提出问题和解决方案!
我无法使用网络索引(http://[my-server]/debug/pprof)中的链接,直到我向您的解决方案添加了几行,如下所示:
...
func AttachProfiler(router *mux.Router) {
router.HandleFunc("/debug/pprof/", pprof.Index)
router.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
router.HandleFunc("/debug/pprof/profile", pprof.Profile)
router.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
// Manually add support for paths linked to by index page at /debug/pprof/
router.Handle("/debug/pprof/goroutine", pprof.Handler("goroutine"))
router.Handle("/debug/pprof/heap", pprof.Handler("heap"))
router.Handle("/debug/pprof/threadcreate", pprof.Handler("threadcreate"))
router.Handle("/debug/pprof/block", pprof.Handler("block"))
}
...
如果有人遇到同样的问题,我希望这有帮助!
答案 1 :(得分:15)
我首选的方法是让net/http/pprof
将自己注册到http.DefaultServeMux
,然后传递所有以/debug/pprof/
开头的请求:
package main
import (
"net/http"
_ "net/http/pprof"
"github.com/gorilla/mux"
)
func main() {
router := mux.NewRouter()
router.PathPrefix("/debug/pprof/").Handler(http.DefaultServeMux)
if err := http.ListenAndServe(":6060", router); err != nil {
panic(err)
}
}
我发现这种方法比依赖隐藏初始化方法实现的方法稳定得多,并且保证你不会错过任何东西。
答案 2 :(得分:12)
对不起那个问题。答案在pprof的init()函数中。只需要将pprof
中的4个函数添加到mux路由器。以下是上面的固定代码。
package main
import (
"fmt"
"github.com/gorilla/mux"
"math"
"net/http"
)
import "net/http/pprof"
func AttachProfiler(router *mux.Router) {
router.HandleFunc("/debug/pprof/", pprof.Index)
router.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
router.HandleFunc("/debug/pprof/profile", pprof.Profile)
router.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
}
func SayHello(w http.ResponseWriter, r *http.Request) {
for i := 0; i < 1000000; i++ {
math.Pow(36, 89)
}
fmt.Fprint(w, "Hello!")
}
func main() {
r := mux.NewRouter()
AttachProfiler(r)
r.HandleFunc("/hello", SayHello)
http.ListenAndServe(":6060", r)
}
答案 3 :(得分:2)
以前的例子对我而言并不奏效。
要在具有gorrila / mux的现有golang项目中使用pprof,请尝试添加:
go func() {
log.Fatal(http.ListenAndServe(":6060", http.DefaultServeMux))
}()
答案 4 :(得分:1)
我做了别的事情,我在另一个端口添加了另一个原生的http服务器,它只是开箱即用
package main
import (
"fmt"
"log"
"net/http"
_ "net/http/pprof"
)
func main() {
go func() {
log.Println(http.ListenAndServe(":6060", nil))
}()
log.Fatalln(http.ListenAndServe(":8080", route.Handlers()))
}
现在pprof端点位于: http://localhost:6060/debug/pprof/并且applcation正在端口上运行:8080
答案 5 :(得分:1)
就这样:
r := mux.NewRouter()
r.PathPrefix("/debug").Handler(http.DefaultServeMux)
答案 6 :(得分:0)
我正在使用https://github.com/julienschmidt/httprouter,但我刚收到谷歌搜索的答案。 这就是我做的事情
router := httprouter.New()
router.Handler("GET", "/debug/pprof/profile", http.DefaultServeMux)
router.Handler("GET", "/debug/pprof/heap", http.DefaultServeMux)
我只需要这两条路线。 这个答案是@damien和@ user983716答案的结合。
答案 7 :(得分:0)
以下方法应该起作用:
import (
"net/http"
_ "net/http/pprof"
)
myrouter.PathPrefix("/debug/pprof/").Handler(http.DefaultServeMux)
答案 8 :(得分:0)
m.PathPrefix("/debug/pprof").Handler(http.DefaultServeMux)
这对我有用。