性能调优原则
- 要依靠数据而不是猜测
- 要定位最大瓶颈而不是细枝末节
- 不要过早优化
- 不要过度优化
性能分析工具 pprof
》说明
- 希望知道应用在什么地方耗费了多少CPU、Memory
- pprof是用于可视化和分析性能、数据的工具
pprof功能简介
pprof排查实战
》搭建pprof实践项目
go tool pprof "http://localhost:6060/debug/pprof/profile?seconds=10"
Flat == Cum,函数中没有调用其他函数
Flat==0,函数中只有其他函数的调用
》CPU
- 命令:list
- 根据指定的正则表达式查找代码行
》CPU
- 命令:web
- 调用关系可视化
》Heap-堆内存
go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/heap"
将有问题的代码注释掉后,重新查看占用内存
》goroutine-协程
go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/goroutine"
》goroutine-协程
- 由上到下表示调用顺序
- 每一块代表一个函数,越长代表占用CPU的时间更长
- 火焰图是动态的,支持点击块进行分析
》goroutine-协程
- 支持搜索,在source视图下搜索wolf
》mutex-锁
go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/mutex"
》block
go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/block"
pprof的采样过程和原理
》CPU
- 采样对象:函数调用和它们占用的时间
- 采样率:100次/秒,固定值
- 采样时间从手动启动到手动结束
graph LR;
开始采样-->设定信号处理函数-->开启定时器;
停止采样-->取消信号处理函数-->关闭定时器;
》heap-堆内存
- 采样程序通过内存分配器在堆上分配和释放的内存,记录分配/释放的大小和数量
- 采样率:每分配512KB记录一次,可在运行开头修改,1为每次分配均记录
- 采样时间:从程序运行开始时到采样时
- 采样指标:alloc_space、alloc_objects、inuse_space、inuse_objects
- 计算方式:inuse = alloc - free
》Goroutine-协程&ThreadCreate-线程创建
》Block-阻塞 & Mutex-锁
小结:
- 掌握常用pprof工具功能
- 灵活运用pprof工具分析解决性能问题
- 了解pprof的采样过程和工作原理
性能调优案列
简介
介绍实际业务服务性能优化的案列
对逻辑相对复杂的程序如何进行性能调优
- 业务服务优化
- 基础库优化
- Go语言优化
业务服务优化
》基本概念
-
服务:能单独部署,承载一定功能的程序
-
依赖:Service A的功能实现依赖
Service B的响应结果,称为 Service A依赖Service B
-
调用链路:能支持一个接口请求的相关服务集合及其相互之间的依赖关系
-
基础库:公共的工具包、中间件
》流程
- 建立服务性能评估手段
- 分析性能数据,定位性能瓶颈
- 重点优化项改造
- 优化效果验证
》建立服务性能评估手段
-
服务性能评估方式
- 单独benchmark无法满足复杂逻辑分析
- 不同负载情况下性能表现差异
-
请求流量构造
- 不同请求参数覆盖逻辑不同
- 线上真实流量情况
-
压测范围
- 单机器压测
- 集群压测
-
性能数据采集
- 单机性能数据
- 集群性能数据
》分析性能数据,定位性能瓶颈
- 使用库不规范
- 高并发场景优化不足
》重点优化项改造
-
正确性是基础
-
响应数据diff
- 线上请求数据录制回放
- 新旧逻辑接口数据diff
》优化效果验证
- 重复压测验证
- 上线评估优化效果
- 关注服务监控
- 逐步放量
- 收集性能数据
》进一步优化,服务整体链路分析
- 规范上游服务调用接口,明确场景需求
- 分析链路,通过业务流程优化提升服务性能
基础库优化
》AB实验SDK的优化
- 分析基础库核心逻辑和性能瓶颈
- 设计完善改造方案
- 数据按需获取
- 数据序列化协议优化
- 内部压测验证
- 推广业务服务落地验证
Go语言优化
总结
- 性能调优原则
- 要依靠数据不是猜测
- 性能分析工具pprof
- 熟练使用pprof工具排查性能问题并了解其基本原理
- 性能调优
- 保证正确性
- 定位主要瓶颈