0
点赞
收藏
分享

微信扫一扫

解决方案(14) golang pprof接入业务同端口


前言

声明: 本文不对pprof基础做讲解,详情可以查阅 https://studygolang.com/pkgdoc 找到net/http/pprof

golang pprof官方介绍里,是采用了默认6060端口,单独开辟了应用进程的pprof服务。它在生产中有以下问题:

  • 需要额外维护不同应用组的pprof端口。(实际上,它可以和业务绑定在同一个路由端口里,减少端口冲突维护)。
  • 在二次开发上,可能想接入鉴权,限频的拦截,官方提供的方式做不到。
  • 官方的路由是f(w http.Writer, r *http.Request),而项目里,可能用到了gin,难以接入。

解决

实现

从gin项目来演示如何让pprof和业务绑定同端口。

本代码片段,为可复制片段,按照项目鉴权等自行适配

func profRouter(r gin.IRoutes) {

// 主页面
r.GET("/debug/pprof/", adapt(pprof.Index))

r.GET("/debug/pprof/profile", profile())

r.GET("/debug/pprof/heap", heap())

r.GET("/debug/pprof/block", block())

r.GET("/debug/pprof/goroutine", goroutine())

r.GET("/debug/pprof/allocs", allocs())
r.GET("/debug/pprof/cmdline", cmdline())
r.GET("/debug/pprof/threadcreate", threadcreate())
r.GET("/debug/pprof/mutex", mutex())
r.GET("/debug/pprof/trace", trace())


}

func adapt(f func(w http.ResponseWriter, r *http.Request)) func(c *gin.Context) {
return func(c *gin.Context) {
f(c.Writer, c.Request)
}
}

func profile() gin.HandlerFunc {
return adapt(pprof.Profile)
//return adapt(pprof.Handler("profile").ServeHTTP)
}

func heap() gin.HandlerFunc {
return adapt(pprof.Handler("heap").ServeHTTP)
}

func block() gin.HandlerFunc {
return adapt(pprof.Handler("block").ServeHTTP)
}

func goroutine() gin.HandlerFunc {
return adapt(pprof.Handler("goroutine").ServeHTTP)
}

func allocs() gin.HandlerFunc {
return adapt(pprof.Handler("allocs").ServeHTTP)
}

func cmdline() gin.HandlerFunc {
return adapt(pprof.Cmdline)
}

func threadcreate() gin.HandlerFunc {
return adapt(pprof.Handler("threadcreate").ServeHTTP)
}

func mutex() gin.HandlerFunc {
return adapt(pprof.Handler("mutex").ServeHTTP)
}

func trace() gin.HandlerFunc {
return adapt(pprof.Trace)
}

func main(){
r := gin.Default()
// pprof路由
profRouter(r)

// 业务路由
xxx(r)
r.Run(":8080")
}

代码中,使用了进行转换,使官方的路由可以适配进来

func adapt(f func(w http.ResponseWriter, r *http.Request)) func(c *gin.Context) {
return func(c *gin.Context) {
f(c.Writer, c.Request)
}
}

效果和官方保持一致
​​​ http://localhost:8080/debug/pprof/​​解决方案(14) golang pprof接入业务同端口_redis

另外,如果pprof的视图很乱,想要了解两个服务增量上的差异,可以使用
go tool pprof -base file1 file2 来比较增量差异。

其中file1和file2是通过类似以下命令拉取的分析文件

curl http://localhost:9112/local/api/debug/pprof/goroutine > file2

仓库

该实现,已经开源到https://github.com/fwhezfwhez/ginprof.git

import "github.com/fwhezfwhez/ginprof"
func main() {
router := gin.New()
ginprof.ProfRouter(router)
...
}


举报

相关推荐

0 条评论