一文带你搞懂Go语言之pprof性能分析利器
前言
作为一个开发,不仅要会写一手好代码,更要会编写高性能的程序;应用程序在运行时,总会出现一些你意想不到的问题,如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的百分比。
注意事项
- 我们只应该在性能测试的时候才能在代码中引入pprof。
- 千万别让外网访问到 pprof,否则可能会导致出现安全问题。
转载自:https://juejin.cn/post/7130498601394356261