利用pprof测试go代码cpu消耗性能,生成图形报告
下面链接可以看看开头 大概了解下pprof
下面两个参考讲解怎么看文字报告、graphviz和火焰图 可以提前看看
原创分享 Go 高性能系列教程:读懂 pprof 生成的报告 - 知乎 (zhihu.com)
pprof性能分析-火焰图 – Heart.Think.Do (heartthinkdo.com)
接入pprof调试接口cpu性能很简单,就下面两行代码,具体可以看下面的demo代码,基于gin框架调试某一个接口
import ( "log" "net/http" _ "net/http/pprof" // 这一行不能忘!!!!!!!!!!!!!!!!!! ) go func() { log.Println(http.ListenAndServe("localhost:8088", nil)) }()
下面代码可以直接运行,运行起来就知道咋回事了
进入graphviz图形界面后,点击view选项卡可以切换图 (图的各个要素代表啥、怎么看自己百度)
top :列出最消耗性能前十(同 pprof 的 top命令) graph : 默认调用流程图 flame graph : 火焰图 peek : 打印调用栈(同 pprof 的 text命令) source : 列出问题代码(同 pprof 的 list命令)
package main import ( "fmt" "github.com/gin-gonic/gin" "log" "net/http" _ "net/http/pprof" // 这一行不能忘!!!!!!!!!!!!!!!!!! ) // 本项目用于调试pprof 专门的写的测试接口:http://localhost:8000/cpu-intensive // 可以看见cpuIntensiveHandler函数里面有两个方法很消耗cpu // // pprof使用方法: // 1、 先安装graphviz 用于图形化显示 cpu消耗图 // 2、 命令行运行 go tool pprof -seconds 10 -http=127.0.0.1:8081 http://localhost:8088/debug/pprof/profile // -seconds 10:统计未来十秒cpu使用情况 (不写参数默认30秒) // -http=127.0.0.1:8081 : 利用8081端口打开一个浏览器页面显示cpu消耗图 // http://localhost:8088/debug/pprof/profile : 代码里面开的一个用于统计的端口 // // 3、 用postman或者别的接口调试工具运行需要调试的接口比如本代码里面的:http://localhost:8000/cpu-intensive (运行测试接口一定要在第二步命令的10s以内 不然统计不了cpu性能) // 4、 十秒一到会自动打开浏览器页面显示cpu消耗graph图 func main() { router := gin.Default() router.GET("/cpu-intensive", cpuIntensiveHandler) go func() { log.Println(http.ListenAndServe("localhost:8088", nil)) }() log.Fatal(router.Run(":8000")) } func TestA() { fmt.Println("=-===============================TestA") } func TestB() { calculatePi2(20000000) fmt.Println("=-===============================TestB") } func cpuIntensiveHandler(c *gin.Context) { fmt.Println("============================开始:") TestA() // 模拟计算密集型的任务 result := calculatePi(10000000) TestA() TestB() c.JSON(http.StatusOK, gin.H{ "result": result, }) } func calculatePi(iterations int) float64 { pi := 0.0 sign := 1.0 for i := 0; i < iterations; i++ { pi += sign / float64(2*i+1) sign *= -1 } return pi * 4 } func calculatePi2(iterations int) float64 { pi := 0.0 sign := 1.0 for i := 0; i < iterations; i++ { pi += sign / float64(2*i+1) sign *= -1 } return pi * 4 }