Golang程序性能分析(二)在Echo和Gin框架中使用pprof
前言
今天繼續(xù)分享使用Go官方庫pprof做性能分析相關的內(nèi)容,上一篇文章:Golang程序性能分析(一)pprof和go-torch中我花了很大的篇幅介紹了如何使用pprof采集Go應用程序的性能指標,如何找到運行緩慢的函數(shù),以及函數(shù)中每一部的性能消耗細節(jié)。這一節(jié)的重點會放在如何在Echo和Gin這兩個框架中增加對pprof HTTP請求的支持,因為pprof只是提供了對net/http包的ServerMux的路由支持,這些路由想放到Echo和Gin里使用時,還是需要有點額外的集成工作。
等集成到框架里,能通過HTTP訪問pprof提供的幾個路由后,go tool pprof工具還是通過訪問這些URL把性能數(shù)拿到本地后來分析的,后續(xù)的性能數(shù)據(jù)采集和分析的操作就跟上篇文章里介紹的完全一樣了,并沒有因為使用的框架不一樣而有什么差別。
在Echo中使用pprof
由于Echo框架使用的復用器ServerMux是自定義的,需要手動注冊pprof提供的路由,網(wǎng)上有幾個把他們封裝成了包可以直接使用, 不過都不是官方提供的包。后來我看了一下pprof提供的路由Handler的源碼,只需要把它轉(zhuǎn)換成Echo框架的路由Handler后即可能正常處理那些pprof相關的請求,具體轉(zhuǎn)換操作很簡單我就直接放代碼了。
func?RegisterRoutes(engine?*echo.Echo)?{
??router?:=?engine.Group("")
??......
??//?下面的路由根據(jù)要采集的數(shù)據(jù)需求注冊,不用全都注冊
?router.GET("/debug/pprof",?echo.WrapHandler(http.HandlerFunc(pprof.Index)))
?router.GET("/debug/pprof/allocs",?echo.WrapHandler(http.HandlerFunc(pprof.Index)))
?router.GET("/debug/pprof/block",?echo.WrapHandler(http.HandlerFunc(pprof.Index)))
?router.GET("/debug/pprof/goroutine",?echo.WrapHandler(http.HandlerFunc(pprof.Index)))
?router.GET("/debug/pprof/heap",?echo.WrapHandler(http.HandlerFunc(pprof.Index)))
?router.GET("/debug/pprof/mutex",?echo.WrapHandler(http.HandlerFunc(pprof.Index)))
?router.GET("/debug/pprof/cmdline",?echo.WrapHandler(http.HandlerFunc(pprof.Cmdline)))
?router.GET("/debug/pprof/profile",?echo.WrapHandler(http.HandlerFunc(pprof.Profile)))
?router.GET("/debug/pprof/symbol",?echo.WrapHandler(http.HandlerFunc(pprof.Symbol)))
?router.GET("/debug/pprof/trace",?echo.WrapHandler(http.HandlerFunc(pprof.Trace)))
}
注冊好路由后還需要對Echo框架的寫響應超時WriteTimeout做一下配置,保證發(fā)生寫超時的時間設置要大于pprof做數(shù)據(jù)采集的時間,這個配置對應的是/debug/pprof路由的seconds參數(shù),默認采集時間是30秒,比如我通常要進行60秒的數(shù)據(jù)采集,那WriteTimeout配置的時間就要超過60秒,具體配置方式如下:
如果pprof做profiling的時間超過WriteTimeout會引發(fā)一個 "profile duration exceeds server's WriteTimeout"的錯誤。
RegisterRoutes(engine)
err?:=?engine.StartServer(&http.Server{
???Addr:??????????????addr,
???ReadTimeout:???????time.Second?*?5,
???ReadHeaderTimeout:?time.Second?*?2,
???WriteTimeout:??????time.Second?*?90,
})
上面兩步都設置完后就能夠按照上面文件里介紹的pprof子命令進行性能分析了
??go?tool?pprof?http://{server_ip}:{port}/debug/pprof/profile
Fetching?profile?over?HTTP?from?http://localhost/debug/pprof/profile
Saved?profile?in?/Users/Kev/pprof/pprof.samples.cpu.005.pb.gz
Type:?cpu
Time:?Nov?15,?2020?at?3:32pm?(CST)
Duration:?30.01s,?Total?samples?=?0
No?samples?were?found?with?the?default?sample?value?type.
Try?"sample_index"?command?to?analyze?different?sample?values.
Entering?interactive?mode?(type?"help"?for?commands,?"o"?for?options)
(pprof)
具體pprof常用子命令的使用方法,可以參考文章Golang程序性能分析(一)pprof和go-torch里的內(nèi)容。
在Gin中使用pprof
在Gin框架可以通過安裝Gin項目組提供的gin-contrib/pprof包,直接引入后使用就能提供pprof相關的路由訪問。
import?"github.com/gin-contrib/pprof"
package?main
import?(
?"github.com/gin-contrib/pprof"
?"github.com/gin-gonic/gin"
)
func?main()?{
??router?:=?gin.Default()
??pprof.Register(router)
??router.Run(":8080")
}
這個包還支持把pprof路由劃分到單獨的路由組里,具體可以查閱gin-contrib/pprof的文檔。
上面這些都配置完,啟動服務后就能使用go tool pprof進行數(shù)據(jù)采集和分析:
內(nèi)存使用信息采集
go?tool?pprof?http://localhost:8080/debug/pprof/heap
CPU使用情況信息采集
go?tool?pprof?http://localhost:8080/debug/pprof/profile
總結(jié)
用go tool pprof能對所有類型的Go應用程序的性能進行分析,這次的文章主要說的是怎么在Echo和Gin這兩個框架里開啟對pprof性能采集的支持,具體對程序性能分析的方法和步驟還是和第一篇Golang程序性能分析(一)pprof和go-torch中重點講的內(nèi)容一樣。
推薦閱讀
