pprof性能调优 | 青训营笔记

108 阅读3分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的的第2篇笔记

pprof性能调优 | 青训营笔记

性能调优原则

  • 要依靠数据不是猜测
  • 要定位最大瓶颈而不是细枝末节
  • 不要过早优化()
  • 不要过度优化(版本更新迭代的不兼容问题)

pprof-功能简介

  • 一个查询耗费CPU、Memory多少的性能分析工具
  • 可视化、分析性能
  • 采样部分-通过采样程序运行时的CPU、堆内存、goroutine、锁竞争.阻塞调用和系统线程的使用数据展示-用户可以通过列表、调用图、火焰图、源码、反汇编等视图去展示采集到的性能指标 image.png

pprof界面

运行main.go主程序(注释是对代码的分析

func main() {
   log.SetFlags(log.Lshortfile | log.LstdFlags)
   log.SetOutput(os.Stdout)

   runtime.GOMAXPROCS(1)              //限制CPU使用数
   runtime.SetMutexProfileFraction(1) //开启锁调用跟踪
   runtime.SetBlockProfileRate(1)     //开启阻塞调用跟踪

   go func() {
      //启动http server 端口号为 6060
      if err := http.ListenAndServe(":6060", nil); err != nil {
         log.Fatal(err)
      }
      os.Exit(0)
   }()

   for {
      for _, v := range animal.AllAnimals {
         v.Live()
      }
      time.Sleep(time.Second)
   }
}

程序运行之后输入 http://localhost:6060/debug/pprof/可以查看pprof监控界面 (我们可以通过这个大概了解程序运行情况并进行性能分析)

各个指标的信息

  • allocs:内存分配情况
  • blocks:阻塞操作情况
  • cmdline:程序启动命令
  • goroutine:当前所有goroutine的堆栈信息
  • heap:堆上内存使用情况(同alloc)
  • mutex:锁竞争操作情况
  • profile: CPU占用情况
  • threadcreate:当前所有创建的系统线程的堆栈信息
  • trace:程序运行跟踪信息 (比较复杂 需要另外的工具解析,暂不涉及)

image.png

优化CPU占用

我们先来看一下程序的CPU占用 通过PID可以看得出来占用量还是很高的 image.png

在TerMinal窗口输入: go tool pprof "http://localhost:6060/debug/pprof/profile?seconds=10" ,先pprof工具采集10秒的数据到profile文件中

  • pro的采样结果是将一段时间内的信息汇总输出到文件中,所以首先需要拿到这个prfie文件。你可以直接使用暴露的接口链接下载文件后使用,也可以直接用ppof工具连接这个接口下载需要的数据。这里我们使用go tool pprof +采样链接来启动采样。
  • 链接中就是刚才扎弹]程序展露出来的接口,如果直接用浏览器打开这个链接,会启动60秒的采样,并在结束的时候下载文件

在窗口中输入top指令, 查看占用CPU资源较多的调用

image.png

  • Flat:当前函数的占用
  • Flat%:Flat占总量的比例
  • Sum%:上面所有行的Flat%总和
  • Cum (Cumulative) :当前函数加上其调用函数的总占用
  • Cum%: Cum占总量的比例

我们将占最大的调用代码所在的位置点开后可以看见这样一串代码 (list Eat 可以看到其代码内容)

func (t *Tiger) Eat() {
   /*log.Println(t.Name(), "eat")
   loop := 10000000000
   for i := 0; i < loop; i++ {
      // do nothing
   }*/
}

我们将其注释掉 重新启动服务后会发现 cpu资源调度一下子就变少了

image.png

同理,我们将其他的性能炸弹一个个的找出来,注释掉,问题就清空啦

以下是本次实验所埋设的炸弹

  • 协程问题 image.png

  • 内存占用 image.png

  • mutex 锁的引用 image.png

  • block 阻塞问题

image.png