Go性能优化 | 青训营笔记

72 阅读4分钟

这是我参与「 第五届青训营 」伴学笔记创作活动的第 3 天 系统性能的分析优化,一定是从大到小的步骤来进行的,即从业务架构的优化,到系统架构的优化,再到系统模块间的优化,最后到代码编写层面的优化。业务架构的优化是最具性价比的,技术难度相对较小,却可以带来大幅的性能提升。

常见性能问题

  1. CPU负载过高
  2. 内存占用过高
  3. 阻塞时间过长
  4. GC时间过于频繁
  5. 协程泄露

go运行状态

  1. CPU profile:报告程序的 CPU 使用情况,按照一定频率去采集应用程序在 CPU 和寄存器上面的数据
  2. Memory Profile(Heap Profile):报告程序的内存使用情况
  3. Block Profiling:报告 goroutines 不在运行状态的情况,可以用来分析和查找死锁等性能瓶颈
  4. 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)
}()

image.png

打开资源管理器查看资源使用情况,可发现共使用了5%cpu资源以及约2GB内存,资源消耗较为严重

image.png

查看指标

http://localhost:6060/debug/pprof/

image.png

排查CPU

截取程序运行10s内的采样结果

go tool pprof http://localhost:6060/debug/pprof/profile?second=10

使用top指令查看cpu资源使用情况

image.png

  • flat 当前函数本身的执行耗时
  • flat% flat占CPU总时间的比例
  • sum% 上面每一行的flat%总和
  • cum 指当前函数本身加上其调用函数的总耗时
  • cum% cum占CPU总时间的比例

flat与cum的关系

  • 当函数不调用其它函数时:flat = cum
  • 当函数只调用其它函数时:falt = 0

使用list XX可查看最消耗资源的函数的程序代码,修改对应代码后即可恢复正常

image.png

上面的例子是在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查看内存消耗情况

image.png

选择view - source查看消耗内存的程序代码

image.png

排查allocs分配内存情况

由于部分内存还可能申请后被垃圾回收,所以还应查看分配内存数据

go tool pprof -http=:8000 http://localhost:6060/debug/pprof/heap

查看sample选项卡

  • alloc_objects: 程序累计申请的对象数
  • inuse_objects: 程序当前持有的对象数
  • alloc_space: 程序累计申请的内存大小
  • inuse_space:程序当前占用的内存大小

选择alloc_space查看累计申请的内存大小

image.png

发现异常值后定位解决异常问题

image.png

排查goroutine协程

go tool pprof -http=:8000 http://localhost:6060/debug/pprof/goroutine

选择flamegraph可查看函数执行时间,由上到下表示调用顺序每一块代表一个函数,越长代表占用CPU的时间更长,火焰图是动态的,支持点击块进行分析

image.png

image.png

排查mutex锁

go tool pprof -http=:8000 http://localhost:6060/debug/pprof/mutex image.png

image.png

排查block阻塞

go tool pprof -http=:8000 http://localhost:6060/debug/pprof/block

image.png

image.png

排查过后的性能指标

image.png

参考文章