一 给项目加上 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 调试确定协程泄露的方法。解决掉协程泄露失控的问题后,如下: