go cpu、内存监控、性能分析:PProf

PProf

PProf 是什么

PProf是 golang 官方提供的性能调优分析工具,用于分析和优化Go程序的性能。

PProf通过收集和分析程序的运行时数据来生成性能分析报告。它使用Go语言的运行时特性,如代码注释和特殊的程序运行标记,来收集性能数据。PProf可以检测和测量程序中的CPU利用率、内存分配、阻塞等情况,并生成可视化的报告和图表,以帮助开发人员理解程序的行为和性能瓶颈。

PProf 以 profile.proto 读取分析样本的集合,并生成报告以可视化并帮助分析数据(支持文本和图形报告)。 profile.proto 是一个 Protobuf v3 的描述文件,它描述了一组 callstack 和 symbolization 信息, 作用是统计分析的一组采样的调用栈,是很常见的 stacktrace 配置文件格式。

有哪几种采样方式

  • runtime/pprof:采集程序(非 Server)的指定区块的运行数据进行分析。
  • net/http/pprof:基于 HTTP Server 运行,并且可以采集运行时数据进行分析。
  • go test:通过运行测试用例,并指定所需标识来进行采集。

支持什么使用模式

  • Report generation:报告生成。
  • Interactive terminal use:交互式终端使用。
  • Web interface:Web 界面。

可以做什么

  • CPU Profiling:CPU 分析,按照一定的频率采集所监听的应用程序 CPU(含寄存器)的使用情况,可确定应用程序在主动消耗 CPU 周期时花费时间的位置。
  • Memory Profiling:内存分析,在应用程序进行堆分配时记录堆栈跟踪,用于监视当前和历史内存使用情况,以及检查内存泄漏。
  • Block Profiling:阻塞分析,记录 Goroutine 阻塞等待同步(包括定时器通道)的位置,默认不开启,需要调用 runtime.SetBlockProfileRate 进行设置。
  • Mutex Profiling:互斥锁分析,报告互斥锁的竞争情况,默认不开启,需要调用 runtime.SetMutexProfileFraction 进行设置。
  • Goroutine Profiling: Goroutine 分析,可以对当前应用程序正在运行的 Goroutine 进行堆栈跟踪和分析。这项功能在实际排查中会经常用到,因为很多问题出现时的表象就是 Goroutine 暴增,而这时候我们要做的事情之一就是查看应用程序中的 Goroutine 正在做什么事情,因为什么阻塞了,然后再进行下一步。

HTTP Server 使用举例

1.代码

提供一个http server,最重要一步,就是在 import 中添加 _ "net/http/pprof" 的引用

import (
	"log"
	"net/http"
	"time"

	_ "net/http/pprof"
)

var datas []string

func main() {
	go func() {
		for {
			log.Printf("len: %d", Add("go-programming-tour-book"))
			time.Sleep(time.Millisecond * 10)
		}
	}()

	_ = http.ListenAndServe("0.0.0.0:6060", nil)
}

func Add(str string) int {
	data := []byte(str)
	datas = append(datas, string(data))
	return len(datas)
}

下载安装 pprof 包,go get github.com/google/pprof 。

启动程序,访问 http://127.0.0.1:6060/debug/pprof/ ,检查是否正常响应。 

2.浏览器访问

访问 http://127.0.0.1:6060/debug/pprof/ ,页面如下:

go cpu、内存监控、性能分析:PProf_第1张图片

allocs: 所有过去内存分配的样本

block: 导致同步阻塞的堆栈跟踪

cmdline: 当前程序的命令行调用

goroutine: 所有当前 goroutine 的堆栈跟踪

heap: 活动对象的内存分配情况。您可以指定 gc GET 参数以在获取堆样本之前运行 GC。

mutex: 争用互斥锁持有者的堆栈跟踪

profile: 默认进行 30s 的 CPU Profiling,得到一个分析用的 profile 文件。您可以在秒 GET 参数中指定持续时间。获取配置文件后,使用 go tool pprof 命令来调查配置文件。

threadcreate: 创建新操作系统线程的堆栈跟踪

trace: 当前程序的执行轨迹。您可以在秒 GET 参数中指定持续时间。获取跟踪文件后,使用 go tool trace 命令来调查跟踪。

3.可视化界面分析profile文件

1、文件下载

浏览器页面直接下载:http://127.0.0.1:6060/debug/pprof/

或者终端命令下载:wget http://127.0.0.1:6060/debug/pprof/profile

有时可能存在网络隔离问题,那也可以这么做:

curl http://localhost:6060/debug/pprof/heap?seconds=30 > heap.out

# 下载heap.out到本地
go tool pprof heap.out

2、文件分析

本地执行终端命令:该命令将在所指定的端口号运行一个 PProf 分析用的站点。

go tool pprof -http=:6001 profile文件 

如果出现错误提示 Could not execute dot; may need to install graphviz.,那么意味着你需要安装 graphviz 组件。参考 安装Graphviz

3、文件内容

通过 PProf 所提供的可视化界面,我们能够更方便、更直观的看到 Go 应用程序的调用链、使用情况等。另外在 View 菜单栏中,PProf 还支持多种分析方式的切换,如下:

go cpu、内存监控、性能分析:PProf_第2张图片

接下来我们将基于 CPU Profiling 所抓取的 Profile 进行一一介绍,而其它 Profile 类型的分析模式也是互通的,只要我们了解了一种,其余的也就会了。 

Top

go cpu、内存监控、性能分析:PProf_第3张图片

  • flat:函数自身的运行耗时。
  • flat%:函数自身在 CPU 运行耗时总比例。
  • sum%:函数自身累积使用 CPU 总比例。
  • cum:函数自身及其调用函数的运行总耗时。
  • cum%:函数自身及其调用函数的运行耗时总比例。
  • Name:函数名。

在大多数的情况下,我们可以通过这五列得出一个应用程序的运行情况,知道当前是什么函数,正在做什么事情,占用了多少资源,谁又是占用资源的大头,以此来得到一个初步的分析方向。

Graph

go cpu、内存监控、性能分析:PProf_第4张图片

该视图展示的为整体的函数调用流程,框越大、线越粗、框颜色越鲜艳(红色)就代表它占用的时间越久,开销越大。相反若框颜色越淡,越小则代表在整体的函数调用流程中,它的开销是相对较小的。

因此我们可以用此视图去分析谁才是开销大头,它又是因为什么调用流程而被调用的。

Flame Graph

go cpu、内存监控、性能分析:PProf_第5张图片

 Flame Graph(火焰图)它是可动态的,调用顺序由上到下(A -> B -> C -> D),每一块代表一个函数、颜色越鲜艳(红)、区块越大代表占用 CPU 的时间更长。同时它也支持点击块深入进行分析,这样子我们就可以根据不同函数的多维度层级进行分析,能够更好的观察其流转并发现问题。

Flame Graph(new)

go cpu、内存监控、性能分析:PProf_第6张图片

Peek

go cpu、内存监控、性能分析:PProf_第7张图片

此视图相较于 Top 视图,增加了所属的上下文信息的展示,也就是函数的输出调用者/被调用者。 

Source

go cpu、内存监控、性能分析:PProf_第8张图片

该视图主要是增加了面向源代码的追踪和分析,可以看到其开销主要消耗在哪里。

安装Graphviz

1、安装Homebrew

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

官网地址:https://brew.sh/index.html 

2、安装graphviz程序。

brew install graphviz

参考

https://golang2.eddycjy.com/posts/ch6/01-pprof-1/

Go程序内存泄露问题快速定位 - MySpace

pprof 性能分析 | Go 语言高性能编程 | 极客兔兔 

https://www.cnblogs.com/jiujuan/p/14598141.html 

你可能感兴趣的:(golang,pprof)