性能分析的场景主要有CPU、Memory、IO、Goroutine、死锁几种
1、两种类型的应用(1)服务型应用 _ "net/http/pprof" 包,专用于采集 web 服务 运行数据的分析。即在运行的服务中通过 API 调用取数据。服务型应用场景中因为应用要一直提供服务。所以 pprof 是通过 API 访问来获取,pprof 使用了默认的 http.DefaultServeMux 挂在这些 API 接口。开发者也可以手动注册路由规则挂载 API,如 r.HandleFunc("/debug/pprof/debugopen", openFunc)
(2)工具型应用 "runtime/pprof" 包,专用于采集 应用程序 运行数据的分析。通过代码手动添加收集命令。工具性应用是一个提供特定功能使用的工具,使用完就会退出进程的应用。开发者手动控制把 profile 文件保存到报告文件中。封装的接口可以调用,如要进行 CPU Profiling,则调用 pprof.StartCPUProfile(w io.Writer) 写入到 w 中,停止时调用 StopCPUProfile();要获取内存数据,直接使用 pprof.WriteHeapProfile(w io.Writer) 函数则可。
2、功能CPU 分析(profile): 你可以在 url 上用 seconds 参数指定抽样持续时间(默认 30s),你获取到概览文件后可以用 go tool pprof 命令调查这个概览
内存分配(allocs): 所有内存分配的抽样
阻塞(block): 堆栈跟踪导致阻塞的同步原语
命令行调用(cmdline): 命令行调用的程序
goroutine: 当前 goroutine 的堆栈信息
堆(heap): 当前活动对象内存分配的抽样,完全也可以指定 gc 参数在对堆取样前执行 GC
互斥锁(mutex): 堆栈跟踪竞争状态互斥锁的持有者
系统线程的创建(threadcreate): 堆栈跟踪系统新线程的创建
trace: 追踪当前程序的执行状况. 你可以用 seconds 参数指定抽样持续时间. 你获取到 trace 概览后可以用 go tool pprof 命令调查这个 trace
2、下载pprof文件curl -o cpu_profile http://127.0.0.1:8888/debug/pprof/profile?seconds=60 || http://127.0.0.1:8888/debug/pprof/profile?seconds=60 || http://127.0.0.1:8888/debug/pprof/block || http://127.0.0.1:8888/debug/pprof/groutines?seconds=60
kubectl cp <ns-name>/<pod_name>:cpu_profile /root/fourier/tmp/cpu_profile
go tool pprof /root/fourier/tmp/cpu_profile
使用tar或zip传到 windows
go tool pprof -http :8888 cpu_profile
注意:go tool 与生成pprof的go版本应一致,否则可能报错 unrecognized profile format
3、命令行工具,即go tool pprof工具go tool pprof [文件或链接]
go tool pprof C:\Users\fourier\Downloads\profile
(1)top命令
top 5
flat: 在给定函数上运行耗时
flat%: 在给定函数上运行耗时总比例
sum%: 给定函数 累计 使用 CPU 总比例
cum: 当前函数 以及包含子函数 的调用运行总耗时
cum%: 同上的 CPU 运行耗时总比例
最后一列为函数名称,详细见后续指标介绍
(2)list命令
list [funcName]
list `*$ 查看所有函数
(3)查看堆情况
$ go tool pprof http://localhost:6060/debug/pprof/heap
Fetching profile over HTTP from http://localhost:6060/debug/pprof/heap
Saved profile in /Users/eddycjy/pprof/pprof.alloc_objects.alloc_space.inuse_objects.inuse_space.008.pb.gz
Type: inuse_space
Entering interactive mode (type "help" for commands, "o" for options)
(pprof) top
Showing nodes accounting for 837.48MB, 100% of 837.48MB total
flat flat% sum% cum cum%
837.48MB 100% 100% 837.48MB 100% main.main.func1
-inuse_space:分析应用程序的常驻内存占用情况
-alloc_objects:分析应用程序的内存临时分配情况
4、web命令及可视化工具需安装https://graphviz.gitlab.io/download,可参考https://www.cnblogs.com/shuodehaoa/p/8667045.html
(1)web UI
go tool pprof -http :8080 C:\Users\fourier\Downloads\profile
go tool pprof -http=:8080 cpu.prof
访问http://127.0.0.1:8080/ui即可看到如下
-VIEW看各种视图
-Top:主要看占用内存当排名信息
-Graph:连接图,主要看调用关系图,并且通过框框的粗细、颜色当深浅、线的实虚、以及数字信息包括执行时间和占比
-FlameGraph:火焰图,要看宽度和深度,heap中宽度表明内存占用大小,
-Peek
-Source
-Disassemble
-SAMPLE:采样信息,包括申请对象、申请空间、占用对象、占用空间的信息
-REFINE:可以精细化视图中的信息
-Focus:聚焦在选中元素的上下游元素
-Ignore:忽略选中当元素,包含其后继元素
-Hide:隐藏选中当元素,但不会隐藏其后继元素
-Show:只显示选中的元素,不包含后继元素
-Showfrom:从选中当某一个元素开始,只列出其后继元素
-CONFIG:能将当前已精细化的页面保存起来
(2)理解指标
flat 表示样本中当前函数占用的CPU时间,cum表示当前函数以及当前函数调用其他函数的时间,sum表示当前函数flat及其调用函数的flat之和。
具体理解为:flat只包含当前函数的栈帧信息,不包括其调用函数的栈帧信息。cum字段既包括当前函数的栈帧信息,也包括其调用函数的栈帧信息,flat%和cum%分别表示flat和cum字段占总字段的百分比。
flat可以让我们知道哪个函数耗时多,而cum可以帮助我们找到是哪些函数调用了这些耗时的(flat值大的)函数。
(3)连接图
web [funcName] 查看函数的连接图
go tool pprof -web C:\Users\fourier\Downloads\profile 查看连接图
节点越大,其flat和flat%越大;
节点的颜色越红,其cum和cum%越大;
线条代表了函数的调用链,线条越粗,代表指向的函数消耗了越多的资源。反之亦然。
线条的样式代表了调用关系:实线代表直接调用;虚线代表中间少了几个节点;带有inline字段表示该函数被内联进了调用方(不用在意,可以理解成实线)。
对于一些代码行比较少的函数,编译器倾向于将它们在编译期展开从而消除函数调用,这种行为就是内联。
连接图中的性能问题一般在最红最粗的线。
(4)火焰图
火焰图的Y 轴表示调用栈,调用顺序是从上到下(有些是从下到上,如火焰一般),每一块都是一个函数,越大代表占用 CPU 时间越长。调用栈越深,火焰就越高,顶部就是正在执行的函数,下方都是它的父函数。
火焰图的X 轴表示抽样数,如果一个函数在 x 轴占据的宽度越宽,就表示它被抽到的次数多,即执行的时间长,通常执行频率是 99Hz(每秒99次),如果99次都返回同一个函数名,那就说明 CPU 这一秒钟都在执行同一个函数,可能存在性能问题。注意,x 轴不代表时间,而是所有的调用栈合并后,按字母顺序排列的。
一般采样记录信息有三个参数:采样的进程号、采样的频率(每秒采样多少次,通常 99 次)、采样持续时间
火焰图的颜色表示 CPU 的繁忙程度。
火焰图主要看顶层的哪个函数占据的宽度最大。有"平顶"(plateaus)则表示该函数可能存在性能问题。但是直接观察"平顶"(plateaus)往往不能快速定位性能问题,因为顶部记录的大多是对底层库函数的调用情况。要快速定位性能问题,首先应该观察业务函数在火焰图中的宽度,然后再往顶部找到第一个库函数来缩小范围,而不是直接看平顶。
火焰图的横向长度表示cum,相比下面超出的一截代表flat
(4)另一种可视化方式
pprof -http=:8080 cpu.prof
有待进一步看一下
5、参考