性能调优实战

265 阅读5分钟

性能调优实战

QQ图片20220524170840.png

性能分析工具

性能调优的核心是性能瓶颈的分析,对于 Go 应用程序,最方便的就是 pprof 工具

pprof 功能说明

pprof 是一个强大的性能分析工具,可以捕捉到多维度的运行状态的数据,下面简单介绍一下pprof的用法。 golang在语言层面集成了profile采样工具,在程序运行过程中可以获取cpu、heap、block、traces等执行信息,这些会涉及到runtime/pprof、net/http/pprof、runtime/trace等package。

  • pprof 是用于可视化和分析性能分析数据的工具
  • 可以知道应用在什么地方耗费了多少 CPU、memory 等运行指标

pprof:

真正分析时常用4种

  • CPU Profiling:CPU 分析,按照一定的频率采集所监听的应用程序 CPU(含寄存器)的使用情况,可确定应用程序在主动消耗 CPU 周期时花费时间的位置

  • Memory Profiling:内存分析,在应用程序进行堆分配时记录堆栈跟踪,用于监视当前和历史内存使用情况,以及检查内存泄漏

  • Block Profiling:阻塞分析,记录 goroutine 阻塞等待同步(包括定时器通道)的位置

  • Mutex Profiling:互斥锁分析,报告互斥锁的竞争情况 数据分析

虽然我们生成了数据,这些数据可以存储到文件里、也可以展示在浏览器中。

但是直接访问这些性能分析数据,我们是分析不过来什么的。Go在1.11版本后在它自带的工具集go tool里内置了pprof工具来分析由pprof库生成的数据文件。

使用go tool pprof分析数据,主要有两种写法:

1.通过路径,如go tool pprof http://localhost:8082/debug/pprof/profile (进入命令行交互模式)

2.通过下载的文件,如go tool pprof cpuprofile (进入命令行交互模式)或者 go tool pprof -http=:9091 cpuprofile(进入web页面)

输入top命令,查看占用cpu资源较多的调用 QQ图片20220524173645.png

每一行表示一个函数的信息。

flat:函数在 CPU 上运行的时间

flat%:函数在CPU上运行时间的百分比

sum%:是从上到当前行所有函数累加使用 CPU 的比例,如第二行sum=48.52=28.79+19.73

cum:这个函数以及子函数运行所占用的时间,应该大于等于flat

cum%:这个函数以及子函数运行所占用的比例,应该大于等于flat%

最后一列:函数的名字

输入web命令,生成一张调用关系图,默认会使了浏览器打开,图中除了每个节点的资源占用以外 ,还会将他们的调用关系穿起来 其中图最明显就是方框最红,粗体的Tiger.Eat函数,比top图更直观些

QQ图片20220524174749.png

定位到问题之后,注释掉tiger的eat方法的耗时操作 在然后查看活动监视器,看到cpu占用明显降低。

![O5)%SG0$LN}R%J22YAOPL6.png

Profile项 说明 详情

allocs 内存分配 从程序启动开始,分配的全部内存

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

cmdline 命令行调用 当前程序的命令行调用

goroutine gorouting 所有当前 goroutine 的堆栈跟踪

heap 堆 活动对象的内存分配抽样。您可以指定 gc 参数以在获取堆样本之前运行 GC

mutex 互斥锁 争用互斥锁持有者的堆栈跟踪

profile CPU分析 CPU 使用率分析。可以在url中,通过seconds指定持续时间(默认30s)。获取配置文件 后,使用 go tool pprof 命令分析CPU使用情况

threadcreate 线程创建 导致创建新操作系统线程的堆栈跟踪

trace 追踪 当前程序的执行轨迹。可以在url中,通过seconds指定持续时间(默认30s)。获取跟踪文件后,使用 go tool trace 命令调查跟踪

QQ图片20220605230508.png

QQ图片20220605230615.png

  • 业务优化
    • 流程

      • 建立服务性能评估手段
      • 分析性能数据,定位性能瓶颈
      • 重点优化项改造
      • 优化效果验证
    • 建立压测评估链路

      • 服务性能评估
      • 构造请求流量
      • 压测范围
      • 性能数据采集
    • 分析性能火焰图,定位性能瓶颈

      • pprof 火焰图
    • 重点优化项分析

      • 规范组件库使用
      • 高并发场景优化
      • 增加代码检查规则避免增量劣化出现
      • 优化正确性验证
    • 上线验证评估

      • 逐步放量,避免出现问题
    • 进一步优化,服务整体链路分析

      • 规范上游服务调用接口,明确场景需求
      • 分析业务流程,通过业务流程优化提升服务性能
  • 基础库优化
    • 适应范围更广,覆盖更多服务

    • AB 实验 SDK 的优化

      • 分析基础库核心逻辑和性能瓶颈
      • 完善改造方案,按需获取,序列化协议优化
      • 内部压测验证
      • 推广业务服务落地验证
  • Go 语言优化
    • 适应范围最广,Go 服务都有收益

    • 优化方式

      • 优化内存分配策略
      • 优化代码编译流程,生成更高效的程序
      • 内部压测验证
      • 推广业务服务落地验证

课后

  • 了解下其他语言的编码规范,是否和 Go 语言编码规范有相通之处,注重理解哪些共同点
  • 编码规范或者性能优化建议大部分是通用的,有没有方式能够自动化对代码进行检测?
  • 使用 Go 进行并发编程时有哪些性能陷阱或者优化手段?
  • 在真实的线上环境中,每个场景或者服务遇到的性能问题也是各种各样,搜索下知名公司的官方公众号或者博客,里面有哪些性能优化的案例?比如 eng.uber.com/category/os…
  • Go 语言本身在持续更新迭代,每个版本在性能上有哪些重要的优化点?

\