文章目录
Go 中监控代码性能的有两个包:
net/http/pprof 用于web应用程序使用
runtime/pprof 用于功能服务程序使用
环境:
window
工具下载: graphviz 官网的失效啦,使用github上的下载
https://graphviz.gitlab.io/_pages/Download/Download_windows.html
- 需要将安装好的加入环境变量
- C:\Program Files (x86)\Graphviz2.38\bin
- 如果运行go tool pprof <执行程序> <prof文件>报错的话,请重启电脑.
linux centos
yum -y install graphviz
mac
runtime/pprof的使用brew install graphviz
运行程序的时候加一个–cpuprofile参数,比如fabonacci --cpuprofile=fabonacci.prof
这样程序运行的时候的cpu信息就会记录到fabonacci.prof中了.
代码
package main
import (
"flag"
"fmt"
"log"
"os"
"runtime"
"runtime/pprof"
)
var (
//接受一个参数,也就一个自定义的文件名,默认:default.prof
cpuProfile = flag.String("cpu_profile", "cpu.prof", "输入一个记录cpu信息的文件名称")
memProfile = flag.String("mem_profile", "mem.prof", "输入一个记录内存信息的文件名称")
)
func main() {
flag.Parse()
if *cpuProfile != "" {//判断值是否为空
f, err := os.Create(*cpuProfile) //创建一个文件.
if err != nil {
log.Fatal("权限不足,无法创建文件", err)
}
err = pprof.StartCPUProfile(f) //开启收集cpu,性能指标信息
if err != nil {
log.Fatal("收集cpu信息失败", err)
}
defer f.Close() //注意这里的顺序, defer是FILO先进后出,必须要在关闭收集句柄之后再关闭,否则无法收集
defer pprof.StopCPUProfile() //关闭收集的句柄
}
//实际的应用程序,一个简单的非波纳契数列
for i := 1; i < 20; i ++ {
ret := fab(i)
fmt.Print(ret, ",")
}
//收集内存信息
if *memProfile != "" {
f, err := os.Create(*memProfile)
if err != nil {
log.Fatal("权限不足,无法创建文件", err)
}
runtime.GC()
if err := pprof.WriteHeapProfile(f); err != nil {
log.Fatal("收集内存信息失败", err)
}
defer f.Close()
}
}
func fab(n int) int {
if n <= 2 {
return 1
}
return fab(n - 1) + fab(n -2)
}
生成cpu,mem收集信息的文件profile
第一步:构建项目
go build -o fab.exe main.go
或
go build
第二步:生成收集的文件
fab.exe -cpu_profile fab_cpu.prof -mem_profile fab_mem.prof
分析profile文件
# 分析cpu信息
go tool pprof fab_cpu.prof
#分析mem信息
go tool pprof fab_mem.prof
go tool pprof 常用命令
Type: cpu
Time: Sep 24, 2019 at 12:52pm (CST)
Duration: 202.94ms, 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)
- 输入 web会弹出一个网页, 查看详细信息
- top 查看排名前n个数据,默认为10。
- tree 以树状图形式显示,默认显示10个。
引用包
import(
_ "net/http/pprof"
)
net/http/pprof包里的部分代码
func init() {
http.HandleFunc("/debug/pprof/", Index)
http.HandleFunc("/debug/pprof/cmdline", Cmdline)
http.HandleFunc("/debug/pprof/profile", Profile)
http.HandleFunc("/debug/pprof/symbol", Symbol)
http.HandleFunc("/debug/pprof/trace", Trace)
}
代码实现
package main
import (
"github.com/labstack/echo"
"log"
"net/http"
_ "net/http/pprof"
)
func main() {
e := echo.New()
e.GET("/v", func(ctx echo.Context) error {
return ctx.String(http.StatusOK, "v100")
})
//用于监控收集数据的端口
go func() {
log.Println(http.ListenAndServe("localhost:6060", nil))
}()
e.Logger.Fatal(e.Start(":8080"))
}
访问
- http://localhost:6060/debug/pprof/
命令行分析数据
使用pprof工具查看堆配置文件:
go tool pprof http://localhost:6060/debug/pprof/heap
查看30秒钟的CPU配置文件
go tool pprof http://localhost:6060/debug/pprof/profile
收集5秒钟的执行轨迹
wget http://localhost:6060/debug/pprof/trace?seconds=5
参考文档
- https://cloud.tencent.com/developer/section/1143647
- https://studygolang.com/articles/12970