Golang 使用pprof

Golang 使用pprof

Golang 中监控代码性能的有两个包

  • net/http/pprof
  • runtime/pprof

pprof 的作用

pprof 是 Golang 语言中分析程序运行性能的工具,它能提供各种性能数据

类型描述
allocs内存分配情况的采样信息
blocks阻塞操作情况的采样信息
cmdline显示程序启动命令及参数
goroutine当前所有协程的堆栈信
heap堆上内存使用情况的采样信息
mutex锁争用情况的采样信息
profileCPU 占用情况的采样信息
threadcreate系统线程创建情况的采样信息
trace程序运行跟踪信息

runtime/pprof 的用法示例

package main

import (
    "flag"
    "fmt"
    "log"
    "os"
    "runtime/pprof"
)

var (
    cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file.")
)

func main() {
    log.Println("begin")
    flag.Parse()

    if *cpuprofile != "" {
        f, err := os.Create(*cpuprofile)
        if err != nil {
            log.Fatal(err)
        }

        pprof.StartCPUProfile(f)
        defer pprof.StopCPUProfile()
    }

    for i := 0; i < 30; i++ {
        nums := fibonacci(i)
        fmt.Println(nums)
    }
}

func fibonacci(num int) int {
    if num < 2 {
        return 1
    }
    return fibonacci(num-1) + fibonacci(num-2)
}
  • go build -o fabonacci
  • ./fabonacci --cpuprofile=fabonacci.prof

net/http/pprof

package main

import (
	"fmt"
	"net/http"
	_ "net/http/pprof"
	"os"
	"time"
)

// 运行一段时间:fatal error: runtime: out of memory
func main() {
	// 开启pprof
	go func() {
		ip := "0.0.0.0:6060"
		if err := http.ListenAndServe(ip, nil); err != nil {
			fmt.Printf("start pprof failed on %s\n", ip)
			os.Exit(1)
		}
	}()

	tick := time.Tick(time.Second / 100)
	var buf []byte
	for range tick {
		buf = append(buf, make([]byte, 1024*1024)...)
	}
}

pprof 包会自动注册 handler, 处理相关的请求:

func init() {
  http.Handle("/debug/pprof/", http.HandlerFunc(Index))
  http.Handle("/debug/pprof/cmdline", http.HandlerFunc(Cmdline))
  http.Handle("/debug/pprof/profile", http.HandlerFunc(Profile))
  http.Handle("/debug/pprof/symbol", http.HandlerFunc(Symbol))
  http.Handle("/debug/pprof/trace", http.HandlerFunc(Trace))
}

启动服务后,直接在浏览器访问:

  • http://$HOST/debug/pprof/

单独查看:

  • cpu(CPU Profiling): $HOST/debug/pprof/profile,默认进行 30s 的 CPU Profiling,得到一个分析用的 profile 文件
  • block(Block Profiling):$HOST/debug/pprof/block,查看导致阻塞同步的堆栈跟踪
  • goroutine:$HOST/debug/pprof/goroutine,查看当前所有运行的 goroutines 堆栈跟踪
  • heap(Memory Profiling):$HOST/debug/pprof/heap,查看活动对象的内存分配情况
  • mutex(Mutex Profiling):$HOST/debug/pprof/mutex,查看导致互斥锁的竞争持有者的堆栈跟踪
  • threadcreate:$HOST/debug/pprof/threadcreate,查看创建新OS线程的堆栈跟踪

进入交互式模式之后,比较常用的有 toplistweb ,traces等命令

  • top
(pprof) top
Showing nodes accounting for 1.55GB, 100% of 1.55GB total
Dropped 2 nodes (cum <= 0.01GB)
      flat  flat%   sum%        cum   cum%
    1.55GB   100%   100%     1.55GB   100%  main.main
         0     0%   100%     1.55GB   100%  runtime.main

top会列出5个统计数据:

  • flat: 本函数占用的内存量。
  • flat%: 本函数内存占使用中内存总量的百分比
  • sum%: 前面每一行flat百分比的和,比如第2行虽然的100% 是 100% + 0%
  • cum: 是累计量,加入main函数调用了函数f,函数f占用的内存量,也会记进来
  • cum%: 是累计量占总量的百分比

list

查看某个函数的代码,以及该函数每行代码的指标信息,如果函数名不明确,会进行模糊匹配,比如list main会列出main.main和runtime.main。

(pprof) list main.main
Total: 1.55GB
ROUTINE ======================== main.main in /home/dyc/data/projects/go/src/go-cn/main.go
    1.55GB     1.55GB (flat, cum)   100% of Total
         .          .     20:	}()
         .          .     21:
         .          .     22:	tick := time.Tick(time.Second / 100)
         .          .     23:	var buf []byte
         .          .     24:	for range tick {
    1.55GB     1.55GB     25:		buf = append(buf, make([]byte, 1024*1024)...)
         .          .     26:	}
         .          .     27:}
(pprof)

traces
打印所有调用栈,以及调用栈的指标信息

(pprof) traces
File: testp
Type: inuse_space
Time: Jan 6, 2020 at 12:49am (CST)
-----------+-------------------------------------------------------
     bytes:  1.55GB
    1.55GB   main.main
             runtime.main
-----------+-------------------------------------------------------
     bytes:  1.24GB
         0   main.main
             runtime.main
-----------+-------------------------------------------------------
     bytes:  1016.83MB
         0   main.main

每个- - - - - 隔开的是一个调用栈,能看到runtime.main调用了main.main,并且main.main中占用了1.55GB内存

web

web命令就会在/tmp下生成svg文件,svg文件是可以在浏览器下看的

(pprof) web

在/tmp下生成 pprof001.svg,浏览器打开

在这里插入图片描述

golang pprof 能帮我们做什么

  • 排查 CPU 占用过高: 使用CPU profile
  • 排查内存占用过高:使用 Heap profiles
  • 排查频繁内存回收:使用 Allocs profiles. GODEBUG=gctrace=1 ./binary | grep gc
  • 排查协程泄露: 使用Goroutine profiles
  • 排查锁的争用: 使用Mutex profiles
  • 排查阻塞操作: 使用Block profiles

最后

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CoLiuRs

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值