Golang性能分析

一、通过pprof实时分析

性能分析的场景主要有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): 每秒采集99次

内存分配(allocs): 堆栈等空间上的内存分配采样,每分配512K字节时取样一次

阻塞(block): 堆栈跟踪导致阻塞的同步原语

命令行调用(cmdline): 命令行调用的程序

goroutine: 当前 goroutine 的堆栈信息

堆(heap): 堆上内存分配的抽样,每分配512K字节时取样一次

互斥锁(mutex): 堆栈跟踪竞争状态互斥锁的持有者

系统线程的创建(threadcreate): 堆栈跟踪系统新线程的创建

trace: 追踪当前程序的执行状况. 你可以用 seconds 参数指定抽样持续时间. 你获取到 trace 概览后可以用 go tool trace命令调查这个 trace

3、下载pprof文件

curl -o cpu_profile http://127.0.0.1:8888/debug/pprof/profile?seconds=60 || http://127.0.0.1:8888/debug/pprof/heap?seconds=60 ||http://127.0.0.1:8888/debug/pprof/allocs?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

go tool pprof -http :8888 cpu_profile

注意:go tool 与生成pprof的go版本应一致,否则可能报错 unrecognized profile format

4、命令行工具,即go tool pprof工具

go tool pprof [文件或链接]

go tool pprof http://127.0.0.1:8081/debug/pprof/allocs

go tool pprof http://127.0.0.1:8081/debug/pprof/profile?seconds=60

go tool pprof C:\Users\fourier\Downloads\profile

go tool pprof http://localhost:6060/debug/pprof/heap

(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:分析应用程序的内存临时分配情况

5、web命令及可视化工具

需安装Download | Graphviz,可参考https://www.cnblogs.com/shuodehaoa/p/8667045.html

(1)web UI

go tool pprof -http=:8080 cpu_profile

访问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)CPU连接图

web [funcName] 查看函数的连接图

go tool pprof -web C:\Users\fourier\Downloads\profile 查看连接图

节点越大,其flat和flat%越大;

节点的颜色越红,其cum和cum%越大;

线条代表了函数的调用链,线条越粗,代表指向的函数消耗了越多的资源。反之亦然。

线条的样式代表了调用关系:实线代表直接调用;虚线代表中间少了几个节点;带有inline字段表示该函数被内联进了调用方(不用在意,可以理解成实线)。

对于一些代码行比较少的函数,编译器倾向于将它们在编译期展开从而消除函数调用,这种行为就是内联。

连接图中的性能问题一般在最红最粗的线。

(4)CPU火焰图

  • 火焰图的Y 轴表示调用栈,调用顺序是从上到下(有些是从下到上,如火焰一般),每一块都是一个函数,越大代表占用 CPU 时间越长。调用栈越深,火焰就越高,顶部就是正在执行的函数,下方都是它的父函数。

  • 火焰图的X 轴表示抽样数,如果一个函数在 x 轴占据的宽度越宽,就表示它被抽到的次数多,即执行的时间长,通常执行频率是 99Hz(每秒99次),如果99次都返回同一个函数名,那就说明 CPU 这一秒钟都在执行同一个函数,可能存在性能问题。注意,x 轴不代表时间,而是所有的调用栈合并后,按字母顺序排列的。

  • 一般采样记录信息有三个参数:采样的进程号、采样的频率(每秒采样多少次,通常 99 次)、采样持续时间

  • 火焰图的颜色表示 CPU 的繁忙程度。

  • 火焰图主要看顶层的哪个函数占据的宽度最大。有"平顶"(plateaus)则表示该函数可能存在性能问题。但是直接观察"平顶"(plateaus)往往不能快速定位性能问题,因为顶部记录的大多是对底层库函数的调用情况。要快速定位性能问题,首先应该观察业务函数在火焰图中的宽度,然后再往顶部找到第一个库函数来缩小范围,而不是直接看平顶。

  • 火焰图的横向长度表示cum,相比下面超出的一截代表flat

(5)内存连接图

-alloc_objects:从程序运行开始申请分配的对象数,不管回收

-alloc_space:从程序运行开始申请分配的内存大小,不管回收

-inuse_objects:采样时间内分配或释放的对象数

-inuse_space:采样时间内分配或释放的内存

6、参考

一次Go服务可用性抖动的问题排查

https://www.cnblogs.com/qcrao-2018/p/11832732.html

分析Go程序的Off-CPU性能

瞬间高并发,goroutine执行结束后的资源占用问题

二、通过core dump在程序crash时自动dump

1、通过ulimit -a查看是否开启了core file,如果是0表示未开启

2、环境变量 GOTRACEBACK设置为crash

export GOBACTRACE=crash

3、设置core dump的路径

查看core dump的路径

cat /proc/sys/kernel/core_pattern

修改core dump的生成路径

 echo '/home/wangtian/coredump_file/core.%e-%p-%s' > /proc/sys/kernel/core_pattern

4、通过delve分析dump内容

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
分析磁盘的实时性能,可以使用Golang中的os/diskusage和syscall/sysinfo包。以下是使用这些包来分析磁盘实时性能的基本步骤: 1. 导入必要的包: ```go import ( "fmt" "os" "syscall" ) ``` 2. 使用os/diskusage包来获取磁盘使用情况: ```go func getDiskUsage(path string) (available uint64, total uint64, used uint64, err error) { fs := syscall.Statfs_t{} err = syscall.Statfs(path, &fs) if err != nil { return } available = fs.Bavail * uint64(fs.Bsize) total = fs.Blocks * uint64(fs.Bsize) used = total - available return } ``` 3. 使用syscall/sysinfo包来获取系统的负载情况: ```go func getSystemLoad() (loadavg [3]float64, err error) { var s syscall.Sysinfo_t if err = syscall.Sysinfo(&s); err != nil { return } uptime := float64(s.Uptime) loadavg[0] = float64(s.Loads[0]) / (1 << 16) loadavg[1] = float64(s.Loads[1]) / (1 << 16) loadavg[2] = float64(s.Loads[2]) / (1 << 16) return } ``` 4. 编写主函数来定期获取磁盘和系统的使用情况,并输出到控制台: ```go func main() { // 磁盘路径 path := "/" // 定期获取磁盘使用情况和系统负载 for { available, total, used, err := getDiskUsage(path) if err != nil { fmt.Println("Error:", err) } else { fmt.Printf("Disk usage: %d / %d (%d%%)\n", used, total, 100*used/total) } loadavg, err := getSystemLoad() if err != nil { fmt.Println("Error:", err) } else { fmt.Printf("System load average: %.2f, %.2f, %.2f\n", loadavg[0], loadavg[1], loadavg[2]) } // 休眠5秒 time.Sleep(5 * time.Second) } } ``` 这样,你就可以使用以上代码来定期获取磁盘和系统的使用情况,并进行分析和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值