Go性能分析工具pprof详解

这篇具有很好参考价值的文章主要介绍了Go性能分析工具pprof详解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


一、什么是pprof

pprof是Go官方提供的性能分析工具,可以分析程序的运行情况,并且提供可视化的功能。prof是profile(画像)的缩写,使用pprof可以分析以下几种指标数据:
go pprof,go,golang,开发语言,后端

  • allocs:程序启动之后内存分配的情况
  • block:导致阻塞操作的一些堆栈跟踪信息
  • cmdline:当前程序启动的命令行
  • goroutine:所有当前 goroutine 的堆栈跟踪信息
  • heap:程序在当前堆上内存分配的情况
  • mutex:锁资源的竞争的堆栈信息
  • profileCPU profile文件。可以在 debug/pprof?seconds=x秒 GET 参数中指定持续时间。获取pprof文件后,使用 go tool pprof x.prof命令分析pprof文件。
  • threadcreate:系统线程的使用情况
  • trace:当前系统的代码执行的链路情况

使用pprof工具主要分析以下几种指标:

  • CPU ProfilingCPU 分析,按照一定的频率采集所监听的应用程序 CPU(含寄存器)的使用情况,可确定应用程序在主动消耗 CPU 周期时花费时间的位置

  • Memory Profiling:内存分析,在应用程序进行堆分配时记录堆栈跟踪,用于监视当前和历史内存使用情况,以及检查内存泄漏

  • Block Profiling:阻塞分析,记录 goroutine 阻塞等待同步(包括定时器通道)的位置

  • Mutex Profiling:互斥锁分析,报告互斥锁的竞争情况。

当程序存在内存或者CPU飙升的情况时,我们可以通过pprof工具来查询问题出现的根源。


二、怎么使用pprof

pprof包含两个相关的库:

  1. runtime/pprof
    主要应用于工具型应用。包含脚本、定时任务等。
    如:对于只跑一次的程序,例如每天只跑一次的离线预处理程序,调用 pprof 包提供的函数,手动开启性能数据采集
  2. net/http/pprof
    主要应用于服务型应用。包含HTTP服务,GRPC服务等。
    如:对于在线服务,对于一个 HTTP Server,访问 pprof 提供的 HTTP 接口,获得性能数据。当然,实际上这里底层也是调用的 runtime/pprof提供的函数,封装成接口对外提供网络访问。

1. 工具型应用

工具型应用主要使用runtime/pprof包实现性能分析。

func main() {
	// --- cpu 分析示例 start---
	// 创建cpu分析文件
	fc, err := os.Create("./cpu.prof")
	if err != nil {
		fmt.Println("create cpu.prof err:", err.Error())
		return
	}
	defer fc.Close()

	// 开始分析cpu
	err = pprof.StartCPUProfile(fc)
	if err == nil {
		defer pprof.StopCPUProfile()
	}
	// --- cpu 分析示例 end---
	
	var count int
	for i := 0; i < 10000; i++ {
		count++
	}

	// --- 内存 分析示例 start---
	fm, err := os.Create("./memory.prof")
	if err != nil {
		fmt.Println("create memory.prof err:", err.Error())
		return
	}
	defer fm.Close()

	// 开始分析内存
	err = pprof.WriteHeapProfile(fm)
	if err != nil {
		fmt.Println("write heap prof err:", err.Error())
		return
	}
	// --- 内存 分析示例 end---

	for i := 0; i < 10000; i++ {
		count++
	}
	fmt.Println("do finish......count:", count)
}

执行go run main.go后,在代码目录下,可以看到生成了cpu.profmemory.prof文件。
通过执行go tool pprof ./memory.prof或者
go tool pprof -http=:8888 ./memory.prof进入命令行模式或者web页面进行性能分析。

执行go tool pprof ./memory.prof进入命令行:
go pprof,go,golang,开发语言,后端

执行go tool -http=:8888 pprof ./memory.prof可进入web页面,更方便查看:
go pprof,go,golang,开发语言,后端
页面展示效果:
go pprof,go,golang,开发语言,后端
SAMPLE各个标签的含义解释:
go pprof,go,golang,开发语言,后端

2. 服务型应用

对于服务类型的应用,主要在服务内部匿名引入net/http/pprof包,然后通过HTTP访问pprof页面。
匿名引入方式为:import _ "net/http/pprof"

package main

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

func main() {
	http.HandleFunc("/", hello)
	err := http.ListenAndServe(":8080", nil)
	if err != nil {
		fmt.Println("ListenAndServe Err:", err.Error())
		return
	}
}

func hello(resp http.ResponseWriter, req *http.Request) {
	fmt.Fprintln(resp, "Hello World, Are You OK?")
}

执行http://localhost:8080/debug/pprof/可以看到画像信息:
go pprof,go,golang,开发语言,后端

但是需要注意,如果HTTP服务不是通过
http.ListenAndServe(":8080", nil)启动的,而是指定第二个参数启动的话,需要自己注册pprof路由。

net/http/pprof/pprof.go的官方源码注释中也提到此种情况:

If you are not using DefaultServeMux, you will have to register handlers with the mux you are using.
如果您不使用DefaultServeMux,则必须向所使用的多路复用器注册pprof处理程序
http.ListenAndServe函数可以传递handler,如果handler不为nil,则说明研发自定义了 ServeMux,否则用的是默认DefaultServeMux

net/http/pprof包中,有init函数

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

所以如果使用默认ServeMux,则不需要注册,但是如果使用自定义的ServeMux,则需要增加注册后,才能获取到pprof

// 自己注册这几个函数
r.HandleFunc("/debug/pprof/", pprof.Index)
r.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
r.HandleFunc("/debug/pprof/profile", pprof.Profile)
r.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
r.HandleFunc("/debug/pprof/trace", pprof.Trace)

另外一种启动pprof的方式在生产环境中更加常用:通过协程另起一个HTTP服务,单独用作pprof分析:

func RegisterProf() {
	go func() {
		if err := http.ListenAndServe(":6060", nil); err != nil {
			panic("pprof server start error: " + err.Error())
		}
	}()
}

三、pprof数据分析

GO官方提供了go tool pprof工具来帮助我们分析pprof生成的数据文件。
使用go tool pprof分析数据,主要有两种模式:

  1. 命令行交互模式
    go tool pprof [file_pprof|url_pprof]
  2. web页面模式
    go tool pprof -http=:6666 [file_pprof|url_pprof]
    其中,file_pprof表示生成的prof分析文件,如cpu.profurl_pprof表示远端服务开启的pprof访问,如http://localhost:8080/debug/pprof/profile

进入命令行交互模式后,可以使用help查看所有子命令,使用help <cmd|option>查看子命令使用方法。如 help、help top

CPU Profiling

浏览器访问/debug/pprof/profile会自动进行 CPU profiling,默认持续 30s,并生成一个文件供下载,可以通过带参数?seconds=60进行60秒的数据采集。

为了模拟请求,使用ab进行压测,
ab -k -c 1 -t 180 -n 100000000 http://localhost:8080/hello

执行go tool pprof http://localhost:8080/debug/pprof/profile后,默认需要等30s才会显示交互

top指令排序展示

go pprof,go,golang,开发语言,后端

每一行表示一个函数的信息,列信息字段解释:

  • flat:函数在 CPU 上运行的时间
  • flat%:函数在CPU上运行时间的百分比
  • sum%:是从第一行到当前行所有函数累加使用 CPU 的比例,如第二行sum=53.85=30.77+23.08
  • cum:这个函数以及子函数运行所占用的时间,应该大于等于flat
  • cum%:这个函数以及子函数运行所占用的比例,应该大于等于flat%
  • 最后一列:函数的名字

web指令生成图示

在交互模式下输入 web,会自动生成一个 svg 文件,并跳转到浏览器打开。

改功能需要安装graphviz后才能使用,安装方法https://shidawuhen.github.io/2020/02/08/go-callvis/ 。

go pprof,go,golang,开发语言,后端
图中每个方框对应应用程序运行的一个函数,方框越大代表函数执行的时间越久(函数执行时间会包含它调用的子函数的执行时间,但并不是正比的关系);方框之间的箭头代表着调用关系,箭头上的数字代表被调用函数的执行时间。

具体细节可以参考:https://github.com/google/pprof/tree/master/doc#interpreting-the-callgraph

runtime netpoll为例:
箭头上的230ms表示该函数总共的执行时间,包含自身和下游所有子节点;
方框中的10ms表示自身的执行时间;
方框中的2.70%表示自身执行时间在该函数总共执行时间的占比在总时间中的占比:2.70 = (10/230)*62.16
方框中的62.16%表示总时间占比,即整个程序耗时占比。

list指令分析函数

确定出哪个函数耗时之后,可以用pprof分析函数中的哪一行导致的耗时,使用子命令:list 函数名。
go pprof,go,golang,开发语言,后端

堆内存分析示例

内存分配既可以发生在堆上也可以在栈上。堆上分配的内存需要垃圾回收或者手动回收(对于没有垃圾回收的语言,例如 C++),栈上的内存则通常在函数退出后自动释放。

Go 语言通过逃逸分析会将尽可能多的对象分配到栈上,以使程序可以运行地更快。

这里说明一下,有两种内存分析策略:一种是当前的(这一次采集)内存或对象的分配,称为 inuse;另一种是从程序运行到现在所有的内存分配,不管是否已经被 gc 过了,称为 alloc

As mentioned above, there are two main memory analysis strategies with pprof. One is around looking at the current allocations (bytes or object count), called inuse. The other is looking at all the allocated bytes or object count throughout the run-time of the program, called alloc. This means regardless if it was gc-ed, a summation of everything sampled.

加上 -sample_index 参数后,可以切换内存分析的类型:
go tool pprof -sample_index=alloc_space http://localhost:8080/debug/pprof/heap
或者
go tool pprof -alloc_space http://localhost:8080/debug/pprof/heap

四种标签:
go pprof,go,golang,开发语言,后端


四、pprof数据分析类型汇总

其他数据的分析和CPU的基本一致。下面列举所有的分类:文章来源地址https://www.toymoban.com/news/detail-625193.html

http://localhost:8080/debug/pprof/ :获取概况信息,即本文第一张图的信息
go tool pprof http://localhost:8080/debug/pprof/allocs : 分析内存分配
go tool pprof http://localhost:8080/debug/pprof/block : 分析堆栈跟踪导致阻塞的同步原语
go tool pprof http://localhost:8080/debug/pprof/cmdline : 分析命令行调用的程序,web下调用报错
go tool pprof http://localhost:8080/debug/pprof/goroutine : 分析当前 goroutine 的堆栈信息
go tool pprof http://localhost:8080/debug/pprof/heap : 分析当前活动对象内存分配
go tool pprof http://localhost:8080/debug/pprof/mutex : 分析堆栈跟踪竞争状态互斥锁的持有者
go tool pprof http://localhost:8080/debug/pprof/profile : 分析一定持续时间内CPU的使用情况
go tool pprof http://localhost:8080/debug/pprof/threadcreate : 分析堆栈跟踪系统新线程的创建
go tool pprof http://localhost:8080/debug/pprof/trace : 分析追踪当前程序的执行状况

参考连接

  1. 一文搞懂pprof
  2. 深度解密Go语言之 pprof
  3. go性能分析工具pprof
  4. Go语言:利用pprof工具排查内存泄漏的示例
  5. Go语言:利用pprof工具查找goroutine(协程)泄漏的示例
  6. go 程序性能调优 pprof 的使用

到了这里,关于Go性能分析工具pprof详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • go 调试利器之pprof指标分析

    Go语言原生支持对于程序运行时重要指标或特征进行分析。pprof是其中一种重要的工具,其不仅可以分析程序运行时的错误(内存泄漏、并发冲突、协程泄漏等),也可以对程序进行优化(比如定位cpu,内存异常逻辑)。由于Go程序运行时不对外暴漏相关指标,因此Go提供了 ru

    2024年02月09日
    浏览(49)
  • Go语言入门记录:从channel的池应用、sync的Pool、benchmark、反射reflect、json处理、http、性能分析和一些编程习惯

    channel的一对一会阻塞,添加buffer不会阻塞。 buffered Channel实现对象池。 sync.Pool 的介绍。 获取时先去私有对象中获取,如果不存在就在相同Processor中的共享池中获取,如果还没有,则去其他Processor中去获取。 存放时,如果私有对象不存在,就放在私有对象中,如果存在就放在

    2024年02月10日
    浏览(36)
  • Go 工具链详解(四): Golang环境变量设置和查看工具 go env

    go env 是 Go 工具链中的一个命令,用于设置和查看当前 Golang 环境的相关信息,对于理解、编译和运行 Golang 程序非常有用。 go 提供的命令及 go 程序的编译运行都会使用到环境变量,如果未设置对应的环境变量,go 则会使用其默认设置。默认情况下,env 以 shell 脚本(在Windo

    2024年02月16日
    浏览(34)
  • Linux系统运维:性能监视和分析工具sar命令详解

    目          录 一、sar工具介绍 二、sar工作原理 (一)原理概述 (二)sar数据收集器 三、sar命令语法 四、sar主要功能介绍 (一)功能概述 (二)CPU统计数据 (三)磁盘I/O统计数据 (四)网络统计数据 1、是使用-n DEV选项的sar输出 2、关于网络错误的信息可以用sar -n EDE

    2024年02月21日
    浏览(59)
  • Golang的trace性能分析

          上一篇是 pprof 的性能分析,通过 pprof 找到我们服务中的瓶颈点来进行优化。Golang的pprof性能分析       一般我们使用 pprof 的 profile 来分析服务的性能,主要是 CPU 方面的耗时和调用链路等。但是光靠 profile 是不够的,细节方面还是要使用 trace 分析并发和阻塞事件

    2024年02月09日
    浏览(24)
  • 辅助性能优化——长安链性能分析工具原理及用法

    如何提升区块链系统性能是很多开发者都会关注的事,但是有些对区块链并非十分熟悉的开发者可能会感到没有头绪。长安链提供了性能分析工具帮助开发者梳理系统耗时,优化系统性能。下面对长安链性能分析工具原理及使用进行介绍。 time_counter.sh是长安链性能分析工具,

    2024年02月13日
    浏览(40)
  • unity 渲染性能分析工具

    既然要优化,肯定要有个目标: pc上一般要求:一秒渲染60帧 移动端:一秒渲染30帧 这应该是最低的要求,如果游戏运行时,游戏帧率有变化,人眼能够明显的感觉到帧率下降。 优化的首要规则是找到性能问题的所在。 一般出现问题不是在cpu就是gpu。 unity内置了性能检测工

    2024年02月03日
    浏览(45)
  • 前端性能分析工具-Lighthouse

    对于前端开发人员来说,除了实现页面功能外,那就是页面的性能响应问题也要关注。同样对于测试人员在进行性能测试时,也要关注前端页面的性能指标。测试前端性能市面上可以用到的工具也比较多,比如可以用 HttpWatch 进行页面的抓取与分析,或者也可以使用抓包工具

    2024年02月11日
    浏览(48)
  • Lighthouse前端性能分析工具

    我们多数性能测试,基本上针对接口的性能测试,很少涉及到前端页面的性能测试。 但影响用户体验的因素除了后端接口数据的返回,还有前端页面的渲染等等。 所以我们除了在开发的过程中注意代码的质量,同时还需要专业的网站测试工具辅助,让我们知道自己的网页还

    2024年02月16日
    浏览(30)
  • 前端性能分析工具——Lighthouse

    1、谷歌插件lighthouse的基本介绍 Lighthouse 是一个网站性能测评工具, 它是 Google Chrome 推出的一个开源自动化工具,能够对 PWA 和网页多方面的效果指标进行评测,并给出最佳实践的建议以帮助开发者改进网站的质量。它的使用方法也非常简单,我们只需要提供一个要测评的网

    2024年02月13日
    浏览(29)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包