pprof 是golang内置的一个性能分析包,使用简单、方便,statsviz 是最近 开源的一个可视化的golang性能观察点
以下是说明treemux 如何集成这两个工具
准备pprof&&statsviz treemux handlerfunc
因为treemux与golang内置的handlerfun有差异所以需要进行下包装
- pprof 包装参考
很简单,一个通用注册handler
func pprofHandler(h http.HandlerFunc) treemux.HandlerFunc {
handler := http.HandlerFunc(h)
return func(w http.ResponseWriter, req treemux.Request) error {
handler.ServeHTTP(w, req.Request)
return nil
}
}
注册pprof handler
const (
defaultPrefix string = "/debug/pprof"
)
// RouterpprofRegister for treemux
func RouterpprofRegister(rg *treemux.TreeMux) {
prefixRouter := rg.NewGroup(defaultPrefix)
{
prefixRouter.GET("/", pprofHandler(pprof.Index))
prefixRouter.GET("/cmdline", pprofHandler(pprof.Cmdline))
prefixRouter.GET("/profile", pprofHandler(pprof.Profile))
prefixRouter.POST("/symbol", pprofHandler(pprof.Symbol))
prefixRouter.GET("/symbol", pprofHandler(pprof.Symbol))
prefixRouter.GET("/trace", pprofHandler(pprof.Trace))
prefixRouter.GET("/allocs", pprofHandler(pprof.Handler("allocs").ServeHTTP))
prefixRouter.GET("/block", pprofHandler(pprof.Handler("block").ServeHTTP))
prefixRouter.GET("/goroutine", pprofHandler(pprof.Handler("goroutine").ServeHTTP))
prefixRouter.GET("/heap", pprofHandler(pprof.Handler("heap").ServeHTTP))
prefixRouter.GET("/mutex", pprofHandler(pprof.Handler("mutex").ServeHTTP))
prefixRouter.GET("/threadcreate", pprofHandler(pprof.Handler("threadcreate").ServeHTTP))
}
}
- statsviz包装
const (
defaultPrefix string = "/debug/statsviz"
)
// RouterStatsvizRegister for treemux
func RouterStatsvizRegister(rg *treemux.TreeMux) {
prefixRouter := rg.NewGroup(defaultPrefix)
prefixRouter.GET("/", pprofHandler(statsviz.Index.ServeHTTP))
prefixRouter.GET("/*path", pprofHandler(statsviz.Index.ServeHTTP))
prefixRouter.GET("/ws", pprofHandler(statsviz.Ws))
}
treemux 集成使用
- go mod
module demoapp
go 1.14
require (
github.com/arl/statsviz v0.1.1
github.com/rongfengliang/treemux-pprof v0.0.0-20201017072014-d71b3788890e // indirect
github.com/rongfengliang/treemux-statsviz v0.0.0-20201017073923-c9cc38c0c032 // indirect
github.com/vmihailenco/treemux v0.1.0
)
- 代码
package main
import (
"fmt"
"net/http"
pprof "github.com/rongfengliang/treemux-pprof"
statsviz "github.com/rongfengliang/treemux-statsviz"
"github.com/vmihailenco/treemux"
)
func corsMiddleware(next treemux.HandlerFunc) treemux.HandlerFunc {
return func(w http.ResponseWriter, req treemux.Request) error {
if origin := req.Header.Get("Origin"); origin != "" {
h := w.Header()
h.Set("Access-Control-Allow-Origin", origin)
h.Set("Access-Control-Allow-Credentials", "true")
}
return next(w, req)
}
}
func main() {
router := treemux.New()
group := router.NewGroup("/api")
group.GET("/v1/:id", func(w http.ResponseWriter, req treemux.Request) error {
id := req.Param("id")
fmt.Fprintf(w, "GET /api/v1/%s", id)
fmt.Fprintf(w, "route: %s", req.Route())
return nil
})
group.GET("/*path", func(w http.ResponseWriter, req treemux.Request) error {
fmt.Println(w, "with catch-all route")
return nil
})
group.GET("/", func(w http.ResponseWriter, req treemux.Request) error {
fmt.Fprintf(w, " api default page")
return nil
})
router.GET("/*path", func(w http.ResponseWriter, req treemux.Request) error {
fmt.Fprintf(w, "with catch-all route")
return nil
})
router.GET("/", func(w http.ResponseWriter, req treemux.Request) error {
fmt.Fprintf(w, "default page")
return nil
})
//routepprofRegister(router)
pprof.RouterpprofRegister(router)
statsviz.RouterStatsvizRegister(router)
router.Use(corsMiddleware)
http.ListenAndServe(":8080", router)
}
- 效果
pprof
statsviz
说明
关于pprof 以及statsviz的treemux包装我已经提供了golang mod 可以使用引用使用
参考资料
https://github.com/rongfengliang/treemux-pprof
https://github.com/rongfengliang/treemux-statsviz
https://github.com/vmihailenco/treemux
https://github.com/arl/statsviz