Profiling 是指在程序执行过程中,收集能够反映程序执行状态的数据。
Go 语言自带的 pprof 库就可以分析程序的运行情况,并且提供可视化的功能。它包含两个相关的库:
1.runtime/pprof:对于只跑一次的程序,例如每天只跑一次的离线预处理程序,调用 pprof 包提供的函数,手动开启性能数据采集。
2.net/http/pprof:对于在线服务,对于一个 HTTP Server,访问 pprof 提供的 HTTP 接口,获得性能数据。当然,实际上这里底层也是调用的 runtime/pprof 提供的函数,封装成接口对外提供网络访问。
如何使用:
1)首先是采集数据 - 两种方式
工具型应用
HTTP Server
2)然后就是进行分析了
Report generation:报告生成
Interactive terminal use:交互式终端使用
Web interface:Web 界面
工具型应用
如果你的应用程序是运行一段时间就结束退出类型。
那么最好的办法是在应用退出的时候把 profiling 的报告保存到文件中,进行分析。对于这种情况,可以使用 runtime/pprof 库。 import "runtime/pprof"
CPU
// 程序运行时开启统计
pprof.StartCPUProfile(w io.Writer)
// 程序结束时关闭
pprof.StopCPUProfile()
示例:
file, _ := os.Create("./cpu.pprof") // 在当前路径下创建一个cpu.pprof文件
pprof.StartCPUProfile(file) // 往文件中记录CPU profile信息
defer func() {
// 退出之前 停止采集
pprof.StopCPUProfile()
file.Close()
}()
服务型应用
如果你的应用程序是一直运行的,比如 web 应用,那么可以使用 net/http/pprof 库,它能够在提供 HTTP 服务进行分析。
直接引入就行了 import _ "net/http/pprof"
Gin框架中引入 pprof 方式
imports "github.com/gin-contrib/pprof"
r:= gin.Default()
pprof.Register(r) // 性能
下载go-wrk
这个是用来进行http接口压测的, 下载地址: http://store.pibigstar.com/go-wrk.exe
官网地址:https://github.com/wg/wrk
压测:
go-wrk -d 500 http://localhost:8080/hello
web查看
浏览器打开:http://localhost:8080/debug/pprof/
allocs
: 内存分配情况block
: 导致阻塞同步的堆栈跟踪cmdline
: 当前程序激活的命令行goroutine
: 当前运行的goroutineheap
: 存活对象的内存分配情况mutex
: 互斥锁的竞争持有者的堆栈跟踪profile
: 默认进行 30s 的 CPU Profilingthreadcreate
: 操作系统线程跟踪trace
: 当前程序执行情况full goroutine stack dump
: 所有goroutine栈输出
数据分析
1.交互式命令
go tool pprof http://localhost:8080/debug/pprof/heap
然后在交互式命令行输入web即可跳转到默认浏览器:
示例:
# 下载cpu profile,默认从当前开始收集30s的cpu使用情况,需要等待30s
go tool pprof http://localhost:8080/debug/pprof/profile #30-second CPU profile
go tool pprof http://localhost:8080/debug/pprof/profile?seconds=120 #wait 120s
# 下载heap profile
go tool pprof http://localhost:8080/debug/pprof/heap #heap profile
# 下载goroutine profile
go tool pprof http://localhost:8080/debug/pprof/goroutine #goroutine profile
# 下载block profile
go tool pprof http://localhost:8080/debug/pprof/block #goroutine blocking profile
# 下载mutex profile
go tool pprof http://localhost:8080/debug/pprof/mutex
常用命令
top n
n不写默认显示10个占用CPU时间最多的函数top -cum
将数据累计查看各个函数CPU占用tree
树形结构查看goroutine情况。list 方法名
查看方法名里面具体调用耗时时长。web
生成SVG函数调用图(需安装graphviz
)pdf
命令可以生成可视化的pdf文件traces
打印所有调用栈exit
退出分析help
命令可以提供所有pprof支持的命令说明
list 可以查看某个函数的代码,以及该函数每行代码的指标信息,如果函数名不明确,会进行模糊匹配,比如list main会列出main.main和runtime.main
traces 打印所有调用栈,以及调用栈的指标信息。使用方式为traces+函数名(模糊匹配)
使用 top 命令:
每一行表示一个函数的信息。
flat:函数在 CPU 上运行的时间
flat%:函数在CPU上运行时间的百分比
sum%:是从上到当前行所有函数累加使用 CPU 的比例,如第二行sum=48.52=28.79+19.73
cum:这个函数以及子函数运行所占用的时间,应该大于等于flat
cum%:这个函数以及子函数运行所占用的比例,应该大于等于flat%
最后一列:函数的名字
我们可以在交互界面输入top(也可以指定个数 比如 top3)来查看程序中占用 CPU 比较多的函数:
http://localhost:8082/debug/pprof/ :获取概况信息,即图一的信息
go tool pprof http://localhost:8082/debug/pprof/allocs : 分析内存分配
go tool pprof http://localhost:8082/debug/pprof/cmdline : 分析命令行调用的程序,web下调用报错
go tool pprof http://127.0.0.1:8810/debug/pprof/goroutine :所有goroutine的信息
go tool pprof http://127.0.0.1:8810/debug/pprof/heap :堆内存的信息
go tool pprof http://127.0.0.1:8810/debug/pprof/profile :CPU的使用情况
go tool pprof http://127.0.0.1:8810/debug/pprof/threadcreate :线程信息
go tool pprof http://127.0.0.1:8810/debug/pprof/trace :分析追踪当前程序的执行状况
go tool pprof http://127.0.0.1:8810/debug/pprof/mutex :锁的信息
go tool pprof http://127.0.0.1:8810/debug/pprof/block :goroutine的阻塞信息
##查看某条调用路径上,当前阻塞在此goroutine的数量:
http://127.0.0.1:8810/debug/pprof/goroutine?debug=1
##查看所有goroutine的运行栈(调用路径),可以显示阻塞了多久和原因:
http://127.0.0.1:8810/debug/pprof/goroutine?debug=2
2、svg
如果觉得在命令行查看不够直观的话,也可以直接输入web命令,生成 svg 图像进行查看。
关于图形的说明:
每个框代表一个函数,理论上框的越大表示占用的CPU资源越多。
方框之间的线条代表函数之间的调用关系,线条上的数字表示函数调用的次数。
方框中的第一行数字表示当前函数占用CPU的百分比,第二行数字表示当前函数累计占用CPU的百分比。
3、火焰图
使用 pprof生成或者 go-torch
go-torch Ubuntun 下安装
git clone https://github.com/brendangregg/FlameGraph.git
cp FlameGraph/flamegraph.pl /usr/local/bin
sudo apt-get install perl
go get -v github.com/uber/go-torch
## 使用,默认停留30秒收据 此期间内可使用hey工具对http服务进行压测
go-torch http://192.168.1.12:8080/debug/pprof/profile
##压测:
go-wrk -d 500 http://localhost:8080
## 生成torch.tvg图片后拉到浏览器里即可
在输入命令:
go-torch -u http://127.0.0.1:8080,想生成火焰图,但是老是抛出错误:
ERROR: No stack counts found,could not generate flame graph: exit status 2。
发现必须在访问程序时,火焰图才能生成。因此通过命令去仿造批量请求:
windows下需要安装:
ActivePerl-5.28.1.0000-MSWin32-x64-92425271(需要加入到系统环境变量中)
FlameGraph/flamegraph.pl 需要加入到系统环境变量中。
安装graphviz:
https://graphviz.gitlab.io/_pages/Download/windows/graphviz-2...
需要加入到系统环境变量中。
生成svg火焰图之后,直接浏览器打开,
在浏览器中即可查看到相关信息了 view 中可以选择查询各种内容:
go tool pprof 自带方式(推荐):
方式一:
go tool pprof -http=:8082 http://localhost:8080/debug/pprof/profile
go tool pprof -http=:8082 http://localhost:8080/debug/pprof/goroutine
# 简单解释
# -http 表示使用交互式web接口查看获取的性能信息,指定可用的端口即可
# debug/pprof/需要查看的指标 (allocs,block,goroutine,heap...)
http://localhost:8082/ui/flamegraph
go tool trace 使用
curl http://127.0.0.1:8082/debug/pprof/trace?seconds=30 > trace.out
go tool trace trace.out 或者
go tool trace -http=localhost:8086 trace.out
go tool pprof 它可以显示在每个函数中花费的CPU时间的百分比。
go tool trace 更适合于找出程序在一段时间内正在做什么.
View trace:查看跟踪
Goroutine analysis:Goroutine 分析
Network blocking profile:网络阻塞概况
Synchronization blocking profile:同步阻塞概况
Syscall blocking profile:系统调用阻塞概况
Scheduler latency profile:调度延迟概况
User defined tasks:用户自定义任务
User defined regions:用户自定义区域
Minimum mutator utilization:最低 Mutator 利用率
View trace
最复杂、最强大和交互式的可视化显示了整个程序执行的时间轴。这个视图显示了在每个虚拟处理器上运行着什么,以及什么是被阻塞等待运行的,注意它只能在chrome上显示。
Goroutine analysis
显示了在整个执行过程中,每种类型的goroutines是如何创建的。在选择一种类型之后就可以看到关于这种类型的goroutine的信息。例如,在试图从mutex获取锁、从网络读取、运行等等每个goroutine被阻塞的时间。
Network/Sync/Syscall blocking profile
这些图表显示了goroutines在这些资源上所花费的时间。它们非常接近pprof上的内存/cpu分析。这是分析锁竞争的最佳选择。
Scheduler latency profiler
为调度器级别的信息提供计时功能,显示调度在哪里最耗费时间。
参考:
https://burxtx.github.io/2018/05/11/%E6%B7%B1%E5%85%A5%E6%B5%85%E5%87%BAGo%E8%AF%AD%E8%A8%80%E6%89%A7%E8%A1%8C%E8%B7%9F%E8%B8%AA/
https://zhuanlan.zhihu.com/p/410590497
https://blog.csdn.net/RA681t58CJxsgCkJ31/article/details/96056719
方式二:
离线生成 gz 文件进行解析.
go tool pprof http://127.0.0.1:8082/debug/pprof/profile?-seconds=30
时间到后会生成一个类似pprof.samples.cpu.003.pb.gz的文件
go tool pprof -http=:8081 pprof.samples.cpu.001.pb.gz
在浏览器中即可查看到相关信息了 view 中可以选择查询各种内容
可视化图形监控—— debugcharts
一个可以实时查看golang程序内存、CPU、GC、协程等变化情况的可视化工具. http://localhost:8080/debug/charts
package main
import (
"fmt"
"net/http"
_ "net/http/pprof" // 必须,引入 pprof 模块
"runtime"
_ "github.com/mkevac/debugcharts" // 可选,添加后可以查看几个实时图表数据
)
func main() {
c := runtime.GOMAXPROCS(10)
fmt.Println(c)
arr := []int{1, 2, 3}
var newArr []*int
for i, _ := range arr {
newArr = append(newArr, &arr[i])
}
for _, v := range newArr {
fmt.Println(*v)
}
http.ListenAndServe("0.0.0.0:8080", nil)
}
go可视化监控工具
pprof
debugcharts
expvar–非嵌入式
prometheus
使用示例:
_ "github.com/mkevac/debugcharts"
"github.com/prometheus/client_golang/prometheus/promhttp"
"net/http"
_ "net/http/pprof"
//监控
go func() {
//提供给负载均衡探活
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("ok"))
})
//prometheus
http.Handle("/metrics", promhttp.Handler())
//pprof, go tool pprof -http=:8080 http://$host:$port/debug/pprof/heap
http.ListenAndServe(":8080", nil)
}()
这个监控包也不错!!!!
https://github.com/arl/statsviz?tab=readme-ov-file
参考文章:
https://segmentfault.com/a/1190000019222661
https://blog.csdn.net/weixin_37717557/article/details/108684433
https://segmentfault.com/a/1190000041261187?utm_source=sf-similar-article
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。