Go进阶-pprof

2023/5/26 go

# PProf是什么

pprof 是用于可视化和分析性能分析数据的工具。

Profiling 是指在程序执行过程中,收集能够反映程序执行状态的数据。 在软件工程中,性能分析(performance analysis,也称为 profiling),是以收集程序运行时信息为手段研究程序行为的分析方法,是一种动态程序分析的方法

go的PProf 主要涉及两个包:

  • net/http/pprof:只是使用runtime/pprof包来进行封装了一下,并在http端口上暴露出来。使用 net/http/pprof 可以做到直接看到当前 web 服务的状态,包括 CPU 占用情况和内存使用情况等。如果服务是一直运行的,如 web 应用,可以很方便的使用这种方式 import "net/http/pprof"。
  • runtime/pprof: pprof开启后,每隔一段时间就会收集下当前的堆栈信息,获取各个函数占用的CPU以及内存资源;最后通过对这些采样数据进行分析,形成一个性能分析报告。适用于:对于本地只跑一次的程序,例如程序中的某一函数调优,调用 pprof 包提供的函数,手动开启性能数据采集。

# go PProf可以分析哪些指标

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

# 如何使用

# 工具型应用

如果你的应用程序是运行一段时间就结束退出类型。那么最好的办法是在应用退出的时候把 profiling 的报告保存到文件中,进行分析。对于这种情况,可以使用runtime/pprof库。 首先在代码中导入runtime/pprof工具:

import "runtime/pprof"
1

# CPU性能分析

开启CPU性能分析:

pprof.StartCPUProfile(w io.Writer)
1

停止CPU性能分析:

pprof.StopCPUProfile()
1

应用执行结束后,就会生成一个文件,保存了我们的 CPU profiling 数据。得到采样数据之后,使用go tool pprof工具进行CPU性能分析。

# 内存性能优化

记录程序的堆栈信息

pprof.WriteHeapProfile(w io.Writer)

1
2

# 服务型应用

如果你使用的是gin框架,那么推荐使用github.com/gin-contrib/pprof (opens new window),在代码中通过以下命令注册pprof相关路由。

pprof.Register(router)
1

端口假设设置的为6060

访问方式:http://{ip}:6060/debug/pprof 比如本地: http://127.0.0.1:6060/debug/pprof/

# Go pprof页指标

打开页面后,我们看到的是go pprof提供的所有指标类型。以一个列表的形式展示,第一列Count数量,第二列Profile 类型。 其中allocs、goroutine、threadcreate 这种可直接展示结果,profile、heap没有展示,点击详情后开始采样。 比如,点击 profile 后,跳转: $HOST:$PORT/debug/pprof/profile ,默认进行 30s 的 CPU Profiling,得到一个分析用的 profile 文件。

如果遇到错误,表示采样时长大于了 server.writetimeout。 profile duration exceeds server's WriteTimeout

conf/config.yam 中 server相关配置,表示整个 serverHTTP接口的时间, 如果采样时间大于30s 必定会超时,所以就不用进行采样了,直接返回错误。

一般情况下我们可手动指定采样时间: http://127.0.0.1:6060/debug/pprof/profile?seconds=1 (opens new window)参数seconds表示采样时长。默认seconds=30s。

  • 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线程的堆栈跟踪

# 如何在web ui查看

pprof 可以用来通过多种方式来分析符合 profile.proto 格式的profiling 的数据,比如命令行交互方式、web ui方式、导出text report的方式等。 profile.proto 是用来描述一组调用堆栈和符号化信息的protobuffer,有关协议缓冲区的详细信息,请参阅https://developers.google.com/protocol-buffers (opens new window)只要符合该格式的数据都可以用pprof工具进行分析。

pprof比较常用的方式是web ui,可读性较好。本文主要以web ui方式讲解下详细的字段值。

# 安装Graphviz

安装Graphviz( http://www.graphviz.org/ )后,可以以图表的方式打开,可读性更好。

# mac安装

brew install graphviz 大概率是不会成功

所以使用port命令安装。

  • 点击下载 port (opens new window)
  • 安装graphviz sudo port install graphviz
  • dot -V 输入版本graphviz即安装成功

# 使用

命令行启动,格式:go tool pprof -http=host:port pprof地址

host可省略,默认为localhost,port也可省略,会随机分配一个可用端口。

示例:

使用pprof工具查看堆配置文件:
go tool pprof -http=:6060 http://localhost:8088/debug/pprof/heap?seconds=5

或者查看30秒钟的CPU配置文件:
go tool pprof -http=:6060 http://localhost:8088/debug/pprof/profile

或者在程序中调用runtime.SetBlockProfileRate之后查看goroutine阻止配置文件:
go tool pprof -http=:6060 http://localhost:8088/debug/pprof/block

或者收集5秒钟的执行轨迹
go tool pprof -http=:6060 http://localhost:8088/debug/pprof/trace?seconds=5

或者在程序中调用runtime.SetMutexProfileFraction之后查看争用互斥锁的持有者:
go tool pprof -http=:6060 http://localhost:8088/debug/pprof/mutex

要查看所有可用的配置文件,请在浏览器中打开http://localhost:6060/debug/pprof/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Last Updated: 2023/5/29
只爱西经
林一