go pprof 性能监测

一、网页访问

import (
	"net/http"
	_ "net/http/pprof"
)
func main() {
	go pprof() //启动pprof
}
func pprof() {
	http.ListenAndServe(":6060", nil) //pprof 默认是6060端口
}

访问链接 :http://127.0.0.1:6060/debug/pprof/
在这里插入图片描述


allocs:程序启动之后内存分配的情况
block:导致阻塞操作的一些堆栈跟踪信息
cmdline:当前程序启动的命令行
goroutine:所有当前 goroutine 的堆栈跟踪信息
heap:程序在当前堆上内存分配的情况
mutex:锁资源的竞争的堆栈信息
profile:CPU profile文件。可以在 debug/pprof?seconds=x秒 GET 参数中指定持续时间。获取pprof文件后,使用 go tool pprof x.prof命令分析pprof文件。
threadcreate:系统线程的使用情况
trace:当前系统的代码执行的链路情况


http://127.0.0.1:6060/debug/pprof/goroutine?debug=1
可以查看goroutine 数量,判断泄露位置
在这里插入图片描述

怎么使用pprof

pprof包含两个相关的库:

  1. runtime/pprof
    主要应用于工具型应用。包含脚本、定时任务等。
    如:对于只跑一次的程序,例如每天只跑一次的离线预处理程序,调用 pprof 包提供的函数,手动开启性能数据采集
  2. net/http/pprof
    主要应用于服务型应用。包含HTTP服务,GRPC服务等。
    如:对于在线服务,对于一个 HTTP Server,访问 pprof 提供的 HTTP 接口,获得性能数据。当然,实际上这里底层也是调用的 runtime/pprof提供的函数,封装成接口对外提供网络访问。

1、工具型

工具型应用主要使用 runtime/pprof 包实现性能分析。

package main

import (
	"bytes"
	"demo/pkg/fmtx"
	"flag"
	"math/rand"
	"os"
	"runtime"
	"runtime/pprof"
	"sync"
	"time"
)

var cpuprofile = flag.String("cpuprofile", "cpu.pprof", "write cpu profile to `file`")
var memprofile = flag.String("memprofile", "mem.pprof", "write mem profile to `file`")

func main() {
	fmtx.Println("w2")
	flag.Parse()
	if *cpuprofile != "" {
		f, err := os.Create(*cpuprofile)
		if err != nil {
			fmtx.Println("could not create CPU profile: ", err)
		}
		defer f.Close()

		if err := pprof.StartCPUProfile(f); err != nil {
			fmtx.Println("could not start CPU profile: ", err)
		}
		defer pprof.StopCPUProfile()
	}

	var wg sync.WaitGroup
	wg.Add(200)

	for i := 0; i < 200; i++ {
		go cyclenum(30000, &wg)
	}

	writeBytes()

	wg.Wait()

	if *memprofile != "" {
		f, err := os.Create(*memprofile)
		if err != nil {
			fmtx.Println("could not create memory profile: ", err)
		}
		defer f.Close()
		runtime.GC()

		if err := pprof.WriteHeapProfile(f); err != nil {
			fmtx.Println("cound not write memory profile: ", err)
		}
	}
	time.Sleep(2 * time.Second)
}

func cyclenum(num int, wg *sync.WaitGroup) {
	slice := make([]int, 0)
	for i := 0; i < num; i++ {
		for j := 0; j < num; j++ {
			j = i + j
			slice = append(slice, j)
		}
	}
	wg.Done()
}

func writeBytes() *bytes.Buffer {
	var buff bytes.Buffer

	for i := 0; i < 30000; i++ {
		buff.Write([]byte{'0' + byte(rand.Intn(10))})
	}
	return &buff
}

运行后可以看到两个文件
cpu.pprof
mem.pprof
执行命令 : go tool pprof .\cpu.pprof
在这里插入图片描述
Type: 分析类型,这里是 cpu
Duration: 程序执行的时长

在这里插入图片描述

top 命令:对函数的 cpu 耗时和百分比排序后输出

字段说明
flat当前函数占用 cpu 耗时
flat %当前函数占用 cpu 耗时百分比
sum%函数占用 cpu 时间累积占比,从小到大一直累积到 100%
cum当前函数加上调用当前函数的函数占用 cpu 的总耗时
%cum当前函数加上调用当前函数的函数占用 cpu 的总耗时占比

找到耗时函数后可以使用 list 逐行分析
在这里插入图片描述
由此可以看出耗时原因是 slice 扩容,可以修改为固定容量

 pprof 图形可视化

除了上面的命令行交互分析,还可以用图形化来分析程序性能。

图形化分析前,先要安装 graphviz 软件,

下载地址:graphviz地址

命令行输入:go tool pprof mem.pprof
输入 web 命令
在这里插入图片描述
生成svg:
在这里插入图片描述
关于图形的一点说明:

  1. 每个框代表一个函数,理论上框越大表示占用的 cpu 资源越多
  2. 每个框之间的线条代表函数之间的调用关系,线条上的数字表示函数调用的次数
  3. 每个框中第一行数字表示当前函数占用 cpu 的百分比,第二行数字表示当前函数累计占用 cpu 的百分比

pprof 图形web可视化

运行命令:go tool pprof -http=:8080 mem.pprof
在这里插入图片描述

在这里插入图片描述
查看top
在这里插入图片描述
查火焰图
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值