Go进阶系列 之 性能分析神器pprof

简介

        Go本身自带的工具链就包含了性能分析工具,pprof就是Go性能分析的利器,它是Go语言自带的包,有如下两种:

  1. runtime/pprof:采集程序(非 Server)的运行数据进行分析
  2. net/http/pprof:采集 HTTP Server 的运行时数据进行分析,这个其实在runtime/pprof包了一层提供了http接口。

作用

  • CPU Profiling: CPU分析,按照一定的频率采集所监听的应用程序的CPU使用情况,可确定应用程序在主动消耗 CPU 周期时花费时间的位置。
  • Memory Profiling:内存分析,在应用程序堆栈分配时记录跟踪,用于监视当前和历史内存使用情况,检查内存泄漏情况。
  • Block Profiling:阻塞分析,记录goroutine阻塞等待同步的位置
  • Mutex Profiling:互斥锁分析,报告互斥锁的竞争情况

使用

有三种方法:

  1. 通过 Web 界面
  2. 通过交互式终端使用
  3. PProf 可视化界面

案例

package main

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

func main() {
   go func() {
      for {
         do("hello,world")
      }
   }()

   fmt.Println("启动服务器...")
   err := http.ListenAndServe(":8080", nil)
   if err != nil {
      panic(err)
   }
}

func do(s string) {
   s1 := make([]string, 0)
   for i := 0; i < 100; i++ {
      s1 = append(s1, s)
   }
}

Http Server程序

通过 Web 界面

启动上面代码后,访问 http://localhost:8080/debug/pprof/ ,就可以看到监控页面了

Go进阶系列 之 性能分析神器pprof_第1张图片

名词解释:

  • allocs:过去所有内存分配的采样
  • block:导致同步原语阻塞的堆栈跟踪
  • cmdline:当前程序的命令行调用
  • goroutine:所有当前goroutine的堆栈跟踪
  • heap:活动对象的内存分配的采样。在获取堆样本之前,可以指定gc GET参数来运行gc。
  • metux:争用互斥锁持有者的堆栈跟踪
  • profile:CPU配置文件。您可以在seconds GET参数中指定持续时间。获取配置文件后,使用go tool pprof命令调查配置文件
  • threadcreate:导致创建新操作系统线程的堆栈跟踪
  • trace:当前程序的执行轨迹。您可以在seconds GET参数中指定持续时间。获取跟踪文件后,使用go tool trace命令调查跟踪

通过交互式终端使用

命令

go tool pprof

1.CPU消耗情况

启动上述代码后,再运行此命令

//这个命令的作用是追踪上面代码60秒内CPU的消耗情况
go tool pprof http://localhost:6060/debug/pprof/profile?seconds=60

Go进阶系列 之 性能分析神器pprof_第2张图片

        执行该命令后,需等待 60 秒(可调整 seconds 的值),pprof 会进行 CPU Profiling。结束后将默认进入 pprof 的交互式命令模式,可以对分析的结果进行查看或导出。具体可执行 pprof help 查看命令说明

2.内存分配

go tool pprof http://localhost:8080/debug/pprof/heap

Go进阶系列 之 性能分析神器pprof_第3张图片

  • -inuse_space:分析应用程序的常驻内存占用情况
  • -alloc_objects:分析应用程序的内存临时分配情况

3.同步原语阻塞的堆栈跟踪

go tool pprof http://localhost:6060/debug/pprof/block

4.互斥锁持有者的堆栈跟踪

go tool pprof http://localhost:6060/debug/pprof/mutex

5.收集 5 秒内的执行路径

go tool pprof http://localhost:6060/debug/pprof/trace?seconds=5

Http Server程序

1.编写测试用例

package data

import "testing"

const url = "https://github.com/EDDYCJY"

func TestAdd(t *testing.T) {
    s := Add(url)
    if s == "" {
        t.Errorf("Test.Add error!")
    }
}

func BenchmarkAdd(b *testing.B) {
    for i := 0; i < b.N; i++ {
        Add(url)
    }
}

2.执行

go test -bench=. -cpuprofile=cpu.prof  //分析CPU
go test -bench=. -memprofile=memory.prof  //分析内存

参数解释:

  • -bench: 通过 go help testflag 查看,按通配运行 benchmarks
  • -cpuprofile: 指定 CPU profiling 的保存文件
  • -memprofile: 指定 Memory profiling 的保存文件

3.启动可视化界面

方法1
go tool pprof -http=:6060 cpu.prof //CPU
//go tool pprof -http=:6060 memory.prof //内存
方法2(不建议用)
go tool pprof cpu.prof 
//go tool pprof memory.prof  
(pprof) web

如果出现错误 Could not execute dot; may need to install graphviz.,就需要装 graphviz 

 Go进阶系列 之 性能分析神器pprof_第4张图片

UI界面

性能分析图

 Go进阶系列 之 性能分析神器pprof_第5张图片

-VIEW 看各种视图

        - Top:类似于 linux top 那种形式。从高到底排序

        - Graph:主要看调用关系图,并且通过框框的粗细、颜色当深浅、线的实虚、 以及数字信息包括执行时间和占比

        - Flame Graph:火焰图,要看宽度和深度,heap 中宽度表明内存占用大小,

        - Peek 类似于 Top 也是从高到底的排序。

        - Source 和交互命令式的那种一样,带有源码标注。

        - Disassemble 显示所有的总量。

- SAMPLE:采样信息,包括申请对象、申请空间、占用对象、占用空间的信息

- REFINE:主要是依据右边的 Search regexp 输入框对 SAMPLE 做一些结果筛选分析

        - Focus:聚焦在选中元素的上下游元素

        - Ignore:忽略选中当元素,包含其后继元素

        - Hide:隐藏选中当元素,但不会隐藏其后继元素

        - Show:只显示选中的元素,不包含后继元素

        - Show from:从选中当某一个元素开始,只列出其后继元素

- CONFIG:能将当前已精细化的页面保存起来

火焰图

         火焰图是基于 perf 结果产生的 SVG 图片,用来展示 CPU 的调用栈。

        Y轴表示调用栈,每一层都是一个函数,调用栈越深火焰就越高,最底部是正在执行的函数,上面是它的父函数。

        X轴表示这个函数的抽样数,如果一个函数在X轴占的越宽,代表抽样数越高,执行CPU的时间越长,注意,X轴不代表时间,而是所有的调用栈合并后,按字母顺序排列的。

        火焰图就是看顶层的哪个函数占据的宽度最大。只要有"平顶"(plateaus),就表示该函数可能存在性能问题

Go进阶系列 之 性能分析神器pprof_第6张图片

参考资料

  • Go性能分析大杀器PPROF

你可能感兴趣的:(GO,进阶系列,golang)