性能调优实战
性能分析工具
性能调优的核心是性能瓶颈的分析,对于 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资源较多的调用
每一行表示一个函数的信息。
flat:函数在 CPU 上运行的时间
flat%:函数在CPU上运行时间的百分比
sum%:是从上到当前行所有函数累加使用 CPU 的比例,如第二行sum=48.52=28.79+19.73
cum:这个函数以及子函数运行所占用的时间,应该大于等于flat
cum%:这个函数以及子函数运行所占用的比例,应该大于等于flat%
最后一列:函数的名字
输入web命令,生成一张调用关系图,默认会使了浏览器打开,图中除了每个节点的资源占用以外 ,还会将他们的调用关系穿起来 其中图最明显就是方框最红,粗体的Tiger.Eat函数,比top图更直观些
定位到问题之后,注释掉tiger的eat方法的耗时操作 在然后查看活动监视器,看到cpu占用明显降低。
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 命令调查跟踪
-
业务优化
-
流程
- 建立服务性能评估手段
- 分析性能数据,定位性能瓶颈
- 重点优化项改造
- 优化效果验证
-
建立压测评估链路
- 服务性能评估
- 构造请求流量
- 压测范围
- 性能数据采集
-
分析性能火焰图,定位性能瓶颈
- pprof 火焰图
-
重点优化项分析
- 规范组件库使用
- 高并发场景优化
- 增加代码检查规则避免增量劣化出现
- 优化正确性验证
-
上线验证评估
- 逐步放量,避免出现问题
-
进一步优化,服务整体链路分析
- 规范上游服务调用接口,明确场景需求
- 分析业务流程,通过业务流程优化提升服务性能
-
-
基础库优化
-
适应范围更广,覆盖更多服务
-
AB 实验 SDK 的优化
- 分析基础库核心逻辑和性能瓶颈
- 完善改造方案,按需获取,序列化协议优化
- 内部压测验证
- 推广业务服务落地验证
-
-
Go 语言优化
-
适应范围最广,Go 服务都有收益
-
优化方式
- 优化内存分配策略
- 优化代码编译流程,生成更高效的程序
- 内部压测验证
- 推广业务服务落地验证
-
课后
- 了解下其他语言的编码规范,是否和 Go 语言编码规范有相通之处,注重理解哪些共同点
- 编码规范或者性能优化建议大部分是通用的,有没有方式能够自动化对代码进行检测?
- 从 github.com/golang/go/t… 中选择感兴趣的包,看看官方代码是如何编写的
- 使用 Go 进行并发编程时有哪些性能陷阱或者优化手段?
- 在真实的线上环境中,每个场景或者服务遇到的性能问题也是各种各样,搜索下知名公司的官方公众号或者博客,里面有哪些性能优化的案例?比如 eng.uber.com/category/os…
- Go 语言本身在持续更新迭代,每个版本在性能上有哪些重要的优化点?
\