go性能调优实战之pprof | 青训营

153 阅读4分钟

pprof 

pprof是go语言自带的性能分析工具,在对go程序进行故障定位、性能调优时应用非常广泛。 pprof是一个分析工具,通过go tool pprof可以直接对采集样本进行分析。 

 什么情况下需要进行性能调优 

一般常规内容: 

  •  cpu:程序对cpu的使用情况 - 使用时长,占比等 
  • 内存:程序对cpu的使用情况 - 使用时长,占比,内存泄露等。如果在往里分,程序堆、栈使用情况 
  • I/O:IO的使用情况 - 哪个程序IO占用时间比较长 

golang 程序中: 

  •  goroutine:go的协程使用情况,调用链的情况 
  • goroutine leak:goroutine泄露检查 
  • go dead lock:死锁的检测分析 
  • data race detector:数据竞争分析,其实也与死锁分析有关 

采样 

样本的采集有三种方式: 

runtime/pprof 直接采样

一般用于工具型程序 

 package main

import (
	"os"
	"runtime/pprof"
)

func main() {
	f, err := os.Create("./profile.out")
	if err != nil {
		os.Exit(1)
		return
	}
	err = pprof.StartCPUProfile(f) //采集cpu profiling,程序退出就结束
	if err != nil {
		os.Exit(1)
		return
	}
	defer pprof.StopCPUProfile()
	
	// do something ...
	
	hf, err := os.Create("./heap.out")
	if err != nil {
		os.Exit(1)
		return
	}
	pprof.WriteHeapProfile(hf) //写入堆信息
}

采样文件会输出到./profile.out中。 

net/http/pprof 借助http服务采样

一般用于服务型程序 

package main

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

func main() {
   http.ListenAndServe("localhost:8080",nil)
   // do something
} 

 pprof在init时会向http.DefaultServerMux注册handler,如果使用自定义的多路复用器,只需要按照init方法,注册handler即可。 

 服务启动后,可以访问http://HOST:PORT/debug/pprof查看采样结果,

 也可以使用curl将采样结果保存到本地文件,curl -sk -v http://HOST:PORT/debug/pprof/profile?secons=30s > profile.out 

Benchmark时采样

 go test -cpuprofile cpu.prof -memprofile mem.prof -bench . 

分析 

分析采样数据有三种方式: 

 直接访问pprof的web网页,查看采样结果。 

  •  Allocs: 查看过去所有内存分配样本 
  • Block:查看导致阻塞同步的堆栈跟踪 
  • cmdline:当前程序命令行 
  • goroutine:当前所有运行的goroutine堆栈跟踪 
  • heap:当前活动对象的内存分配情况 
  • mutex:争用互斥锁的竞争者的堆栈跟踪
  • profile:默认进行30s的cpu profiling,生成profile文件
  •  threadcreate:导致创建新线程的堆栈跟踪 

trace 通过命令行交互方式查看 

 可以通过go tool pprof -h 查看可选参数 

 go tool pprof [source|binary]
// go tool pprof cpuprofile.pprof
// go tool pprof http://HOST:PORT/debug/pprof/heap
// go tool pprof -svg http://HOST:PORT/debug/pprof/heap >heap.svg 

进入交互命令后,可以使用命令进行查看分析: 

  •  help可以查看帮助信息,o查看选项信息 
  • top、text对结果进行排序后展示 
  1. flat表示当前函数占用的cpu时间 
  2. flat%表示当前函数占cpu的占总用时间的百分比 
  3. sum%表示flat%的累积值 
  4. cum表示当前函数以及当前函数调用其他函数的时间,比如a调用b,那么a的cum的值就是包含b的调用时间,火焰图就是使用的cum 
  5. cum%表示当前函数占总占用时间的百分比 
  • 通过top可以看出具体哪个函数比较耗时 
  • 使用list func1分析具体的函数,找到耗时的语句进行优化 
  • svg生成svg格式的输出 

通过UI界面查看(推荐)

  •  需要先安装graphviz软件,安装好将bin目录添加到环境变量,并使用dot -v验证是否装好。 
  • 执行go tool pprof -http=:8888 heap.out 
  • 执行之后会在浏览器打开一个UI界面 

UI界面包含三个栏目:

 VIEW 可以选择展示的形式,有top、graph、flamegraph等 

SAMPLE 选择展示的内容 

REFINE 配合Search regex对展示结果进行筛选 

关于图形的一点说明: 

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

火焰图说明:

  •  火焰图 svg 文件,你可以点击上面的每个方块来查看分析它上面的内容。 
  •  火焰图的调用顺序从下到上,每个方块代表一个函数,它上面一层表示这个函数会调用哪些函数,方块的大小代表了占用 CPU 使用时长长短。