这是我参与「 第五届青训营 」伴学笔记创作活动的第 3 天 系统性能的分析优化,一定是从大到小的步骤来进行的,即从业务架构的优化,到系统架构的优化,再到系统模块间的优化,最后到代码编写层面的优化。业务架构的优化是最具性价比的,技术难度相对较小,却可以带来大幅的性能提升。
常见性能问题
- CPU负载过高
- 内存占用过高
- 阻塞时间过长
- GC时间过于频繁
- 协程泄露
go运行状态
- CPU profile:报告程序的 CPU 使用情况,按照一定频率去采集应用程序在 CPU 和寄存器上面的数据
- Memory Profile(Heap Profile):报告程序的内存使用情况
- Block Profiling:报告 goroutines 不在运行状态的情况,可以用来分析和查找死锁等性能瓶颈
- Goroutine Profiling:报告 goroutines 的使用情况,有哪些 goroutine,它们的调用关系是怎样的
性能分析实例
pprof
在 Go 语言中,pprof是用于可视化和分析性能分析数据的工具,pprof以 profile.proto 读取分析样本的集合,并生成报告以可视化并帮助分析数据(支持文本和图形报告)。
下载运行
下载pprof-practice 运行main.go控制台开始打印日志
go func() {
// 默认启动端口为6060
if err := http.ListenAndServe(":6060", nil); err != nil {
log.Fatal(err)
}
os.Exit(0)
}()
打开资源管理器查看资源使用情况,可发现共使用了5%cpu资源以及约2GB内存,资源消耗较为严重
查看指标
排查CPU
截取程序运行10s内的采样结果
go tool pprof http://localhost:6060/debug/pprof/profile?second=10
使用top指令查看cpu资源使用情况
- flat 当前函数本身的执行耗时
- flat% flat占CPU总时间的比例
- sum% 上面每一行的flat%总和
- cum 指当前函数本身加上其调用函数的总耗时
- cum% cum占CPU总时间的比例
flat与cum的关系
- 当函数不调用其它函数时:flat = cum
- 当函数只调用其它函数时:falt = 0
使用list XX可查看最消耗资源的函数的程序代码,修改对应代码后即可恢复正常
上面的例子是在cmd黑窗口下运行的,数据不太直观,pprof也提供了一套ui界面可以更为直观的展示数据 在,go tool pprof下输入web命令,注意默认端口为6060
go tool pprof -http=:8000 http://localhost:6060/debug/pprof/profile 查看cpu占用
注意,需要提前安装 Graphviz 用于画图
下载地址:graphviz.gitlab.io/download/
windows:graphviz.gitlab.io/_pages/Down…
解压下,添加环境变量 Path下添加 C:\Go\graphviz\bin
测试:命令提示符下 dot -V 打印版本信息 可以打印信息就是已经安装成功
访问地址:http://localhost:8000/ui/
排查heap堆内存
go tool pprof -http=:8000 http://localhost:6060/debug/pprof/heap
选择view - top查看内存消耗情况
选择view - source查看消耗内存的程序代码
排查allocs分配内存情况
由于部分内存还可能申请后被垃圾回收,所以还应查看分配内存数据
go tool pprof -http=:8000 http://localhost:6060/debug/pprof/heap
查看sample选项卡
- alloc_objects: 程序累计申请的对象数
- inuse_objects: 程序当前持有的对象数
- alloc_space: 程序累计申请的内存大小
- inuse_space:程序当前占用的内存大小
选择alloc_space查看累计申请的内存大小
发现异常值后定位解决异常问题
排查goroutine协程
go tool pprof -http=:8000 http://localhost:6060/debug/pprof/goroutine
选择flamegraph可查看函数执行时间,由上到下表示调用顺序每一块代表一个函数,越长代表占用CPU的时间更长,火焰图是动态的,支持点击块进行分析
排查mutex锁
go tool pprof -http=:8000 http://localhost:6060/debug/pprof/mutex
排查block阻塞
go tool pprof -http=:8000 http://localhost:6060/debug/pprof/block
排查过后的性能指标