一 给项目加上 pprof
1 简单的 http 服务直接使用 _ "net/http/pprof"
package main import ( // 略 _ "net/http/pprof" // 会自动注册 handler 到 http server,方便通过 http 接口获取程序运行采样报告 // 略 ) func main() { // 略 runtime.GOMAXPROCS(1) // 限制 CPU 使用数,避免过载 runtime.SetMutexProfileFraction(1) // 开启对锁调用的跟踪 runtime.SetBlockProfileRate(1) // 开启对阻塞操作的跟踪 go func() { // 启动一个 http server,注意 pprof 相关的 handler 已经自动注册过了 if err := http.ListenAndServe(":8023", nil); err != nil { log.Fatal(err) } os.Exit(0) }() // 略 }
2 gowork 项目使用 gin 框架的,pprof 使用 "github.com/DeanThompson/ginpprof"
package main import ( "github.com/gin-gonic/gin" "github.com/DeanThompson/ginpprof" ) func main() { router := gin.Default() router.GET("/ping", func(c *gin.Context) { c.String(200, "pong") }) // automatically add routers for net/http/pprof // e.g. /debug/pprof, /debug/pprof/heap, etc. ginpprof.Wrapper(router) router.Run(":8023") }
2 运行项目,可以在 http://localhost:8023/debug/pprof/goroutine?debug=1 看到输出的信息。
可以看到,刚开始协程 total:12, 然后做一些引起开协程并结束动作,看看协程的状态:
这时协程已经失控了。
我们使用命令行 go 自带的工具命令
go tool pprof http://localhost:8023/debug/pprof/goroutine 会返回一个交互对话框,
这里使用 top, list ×××, web 命令查看具体信息
list 具体某一条
web 命令,虽然这个命令的名字叫“web”,但它的实际行为是产生一个 .svg 文件,并调用你的系统里设置的默认打开 .svg 的程序打开它。如果遇到 failed to execute dot. Is Graphviz installed? Error: exec: "dot": executable file not found in $PATH 错误,需要安装 Graphviz ,ubuntu 下安装直接 sudo apt-get install graphviz。好了,我在软件中做了一些 ssh 的操作,这些操作会引起后台开启协程,在浏览器中会看到下图:
这里图片不是很清晰,主要想说明 pprof 调试确定协程泄露的方法。解决掉协程泄露失控的问题后,如下:
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于