Go的性能调优实战 | 豆包MarsCode AI刷题

123 阅读3分钟

性能调优原则

  • 要依靠数据不要进行猜测
  • 要定位最大瓶颈而不是细枝末节
  • 不要过早优化
  • 不要过度优化

性能分析工具:pprof

pprof是用于可视化和分析性能、分析数据的工具,能告诉我们,应用在什么地方耗费了多少CPU和内存资源。

图片.png

pprof排查实战

搭建pprof实践项目

通过git工具将项目clone到本地

git clone git@github.com:wolfogre/go-pprof-practice.git

运行该项目并登入:http://localhost:6060/debug/pprof/ 即可进入实践项目

图片.png 如果输入以上网址打不开,可能是端口被占用了,可以在项目main.go文件下指定服务器地址:

if err := http.ListenAndServe("localhost:6060", nil); err != nil {
   log.Fatal(err)
}

CPU排查

在运行pprof项目后,可以在终端输入

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

来记录未来10s内CPU性能状态。

命令:top

在这之后在控制台中输入top来查看函数消耗CPU情况。

图片.png 其中:

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

由上图可知函数tiger.(*Tiger).Eat 消耗了绝大部分CPU性能。

当flat==cum时,代表该函数没有调用其他函数,CPU消耗全部由自己提供。当flat = 0,代表该函数中只有其他函数的调用

命令:list

知道了问题函数在哪,就可以对其进一步排查,输入指令:list Eat

图片.png 可以很明显看到第24行中的for循环资源占用最大

Heap-堆内存分析

运行项目后在终端输入:

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

图片.png

如果输入上述命令没有弹出该页面,可能是因为没有安装graphviz。官网地址:graphviz.gitlab.io/download/ 注:安装后需要将它的bin文件夹加入到系统环境变量中。

上图中可以看到mouse.(*Mouse).Live函数所占的内存过高

goroutine-协程分析

保持测试项目运行,输入命令行:

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

选择VIEW->Flame Graph可切换为火焰图:

图片.png

火焰图从上到下可表示函数的调用顺序,每一个小块代表了一个函数。块长代表了占用CPU的时间。可以看到wolf.(*Wolf).Drink.func1,这个函数的协程占用了大部分CPU时间

mutex-锁分析

go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/mutex"

图片.png

问题函数:sync (*Mutex) Unlock。

block-阻塞

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

图形化操作与上述操作基本一致。

block的命令行操作,其中过滤了cum较小的函数过滤掉了

go tool pprof "http://localhost:6060/debug/pprof/block"

图片.png 其中过滤掉了cum<=5.92s的函数。