一文带你搞懂Go语言之pprof性能分析利器

·  阅读 266

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第15天,点击查看活动详情

前言

作为一个开发,不仅要会写一手好代码,更要会编写高性能的程序;应用程序在运行时,总会出现一些你意想不到的问题,如cpu使用率过高、内存占用不断增大,出现Groutine数量暴涨等崩溃的问题。如果在程序出现性能问题的时候,如何快速定位和解决问题,golang自带的性能剖析工具--pprof,可以帮助定位程序中可能存在的问题。本文主要介绍一下pprof的应用,希望对你有所帮助。

什么是pprof

Profiling就是对应用的画像,是指在程序运行过程中,收集能够反应程序执行状态的数据,如应用使用了多少CPU资源、占用了多少内存、开启了多少个Groutine等,知道了这些,我们就能对应用进行规划,也能快速定位性能瓶颈。

Go语言自带的pprof库就可以分析程序的运行情况,并且提供可视化的功能。它包含两个相关的库:

  • runtime/pprof:对于只跑一次的程序,如每天只执行一次的离线处理程序,调用pprof包提供的函数,手动开启性能数据采集。
  • net/http/pprof:对于在线服务,访问pprof提供的http接口,获得性能数据。实际上这里底层也是调用的runtime/pprof提供的函数,只不过是这里封装成接口对外提供网络访问。

pprof开启后,每隔一段时间(10ms)就会收集下当前的堆栈信息,获取各个函数占用的CPU以及内存资源;最后通过对这些采样数据进行分析,形成一个性能分析报告。

能干什么

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

使用

我们可以通过 报告生成、Web 可视化界面、交互式终端 三种方式来使用 pprof。

引入pprof

import _ "net/http/pprof"
复制代码

写一个简单的demo,模拟内存泄露。

package main

import (
	"log"
	"math/rand"
	"net/http"
	_ "net/http/pprof"
)

func main() {
	go func() {
		log.Println(http.ListenAndServe("localhost:9090", nil))
	}()
	for i := 0; i < 1000; i++ {
		go worker()
	}
	select {}
}

func worker() {
	var slice []int64
	for i := 0; i < 10000; i++ {
		slice = append(slice, rand.Int63())
	}
}
复制代码

使用go再带的pprof查看

代码中监听了 9090 端口,在浏览器中输入 http://127.0.0.1:9090/debug/pprof/

引入pprof

Profile信息描述:

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

通过交互式终端使用

go tool pprof最简单的使用方式为:

// binary 是应用的二进制文件,用来解析各种符号;
// source 表示 profile 数据的来源,可以是本地的文件,也可以是 http 地址。
go tool pprof [binary] [source]
复制代码

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

直接使用如下命令,则不需要通过点击浏览器上的链接就能进入命令行交互模式:

go tool pprof http://127.0.0.1:9090/debug/pprof/profile?seconds=60 
复制代码

需要先后台采集一段时间的数据,再将数据文件下载到本地,最后进行分析。上述的 Url 后面还可以带上时间参数:?seconds=60,自定义 CPU Profiling 的时长。

通过UI界面查看

可以直接输入web,需要安装 graphviz,pprof 能够借助 grapgviz 生成程序的调用图,会生成一个 svg 格式的文件,直接在浏览器里打开(可能需要设置一下 .svg 文件格式的默认打开方式)

macos:

brew install graphviz
复制代码

如果安装出现错误解决Error: No such file or directory @ rb_sysopen可以参考:juejin.cn/post/713043…

windows:

下载地址:graphviz.gitlab.io/_pages/Down…

浏览器打开:

关于图形的说明: 每个框代表一个函数,理论上框的越大表示占用的CPU资源越多。 方框之间的线条代表函数之间的调用关系。 线条上的数字表示函数调用的次数。 方框中的第一行数字表示当前函数占用CPU的百分比,第二行数字表示当前函数累计占用CPU的百分比。

注意事项

  1. 我们只应该在性能测试的时候才能在代码中引入pprof。
  2. 千万别让外网访问到 pprof,否则可能会导致出现安全问题。
分类:
后端
收藏成功!
已添加到「」, 点击更改