7.3 性能分析工具
分析-Profile
- 网页
- 可视化终端
工具-Tool
- runtime/pprof
- net/http/pprof
展示-View
- Top
- 调用图-Graph
- 火焰图-Flame Graph
- Peek
- 源码-Source
- 反汇编-Disassemble
采样-Sample
- CPU
- 堆内存-Heap
- 协程-Goroutine
- 锁-Mutex
- 阻塞-Block
- 线程创建-ThreadCreate
排查实战:
要搭建一个pprof实践项目,首先下载源代码,达到能够编译运行的目的,且这一操作会占用1个CPU核心以及超过1GB的内存,提前埋入了一些炸弹代码,注意电脑性能。通过Github链接学习:go-pprof-practice
对 CPU 检查: 除了在浏览器内打开本地服务器网页端进行检查,还可以通过go tool:
go tool pprof "http://localhost:6060/debug/pprof/profile?seconds=10"
输入 top 命令,查看CPU占用情况,可以找到占用资源最多的函数。其中有一些指标:
flat 当前函数本身的执行耗时 flat% flat占CPU总时间的比例 sum% 上面每一行的flat% 总和 cum 指当前函数本身加上其调用函数的总和 cun% cum占CPU总时间的比例
输入 list 命令,可以根据指定的正则表达式查找代码行。 输入 web 命令,可以调用关系可视化。
对堆内存检查:
go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/heap"
输入命令后,点击视图View可以选择不同的种类View,Sample有alloc_objects作为程序累计申请的对象数量、inuse_objects作为程序当前持有的对象数量、alloc_space作为程序累计申请的内存大小, inuse_space作为程序当前占用的内存大小。
7.4 性能调优实战案例
cpu:
采样对象:函数调用和它们占用的时间
采样率:100次每秒,固定值
采样时间:从手动启动到手动结束
操作系统:每10秒向进程发送一次SIGPROF信号
进程:每次接受SIGPROF会记录调用堆栈
写缓冲:每100毫秒读取已经记录的调用栈并写入输出流
Heap堆内存:
采样程序通过内存分配器在堆上分配和释放的内存,记录分配/释放的大小和数量
采样率:每分配512kb记录一次,可在运行开头修改,1为每次分配均记录
采样时间:从程序运行开始到采样时
采样指标:alloc_space,alloc_objects,inuse_space,inuse_objects
计算方式:inuse = alloc-free
Gorountine 协程 & ThreadCreae 线程创建:
Goroutine:记录所有用户发起且在运行中的 gorountine (即入口非runtime开头的) runtime.main 的调用栈信息
threadCreate:记录程序创建的所有系统线程信息
Block & Mutex 锁:
阻塞操作:
采样阻塞操作的次数和耗时
采样率:阻塞耗时超阈值值的才会被记录,1为每次阻塞均记录
锁竞争:
采样争抢锁的次数和耗时
采样率:只记录固定比例的锁操作,1为每次加锁均记录
性能调优案例:
-
业务服务优化,基本概念:
服务:能单独部署,承载一定功能的程序
依赖: Service A 的功能实现依赖 Service B 的响应结果,称为 Service A 依赖 Service B
调用链路: 能支持一个接口请求的相关服务集合及其相互之间的依赖关系
基础库:公共的工具包、中间件
-
流程
建立服务性能评估手段
-
基础库优化
分析基础库核心逻辑和性能瓶颈
- 设计完善改造方案
- 数据按需获取
- 数据序列化协议优化
-
go语言优化
编译器&运行时优化
- 优化内存分配策略
- 优化代码编译逻辑,生成更高效的程序
- 内部压测验证
- 推广业务服务落地验证
优点
- 接入简单,只需要调整编译配置
- 通用性强
总结:
性能调优原则:要依靠数据不是猜测
性能分析工具 pprof:熟练使用 pprof 工具排查性能问题并了解其基本原理