性能分析工具 pprof: 性能调优的前提是对应用程序性能表现有实际的数据指标,对于Go程序,有一个很方便的工具就是pprof!
这里有一个开源项目,已经制造了一些问题代码,需要进行排查
wolfogre/go-pprof-practice: go pprof practice. (github.com)
实际分析排查过程 排查 CPU 问题
命令行分析 go tool pprof "http://localhost:6060/debug/pprof/profile?seconds=10"
top 命令 list 命令
熟悉 web 页面分析
调用关系图,火焰图
go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/cpu"
排查堆内存问题
go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/heap"
排查协程问题
go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/goroutine"
排查锁问题
go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/mutex"
排查阻塞问题
go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/block"
pprof 的采样过程和原理
CPU 采样
堆内存采样
协程和系统线程采样
阻塞操作和锁竞争采样
CPU采样
CPU采样会记录所有调用栈和他们所占用的时间
在采样时,进程会每秒暂停一百次,每次记录当前的调度信息。汇总后,根据调用栈在采样中出现的次数来推断函数的运行时间
堆内存采样
采样程序通过内存分配器在堆上分配和释放的内存,记录分配/释放的内存大小和数量
采样率:每分配512KB记录一次
采样时间:从程序运行开始到采样时
采样指标:alloc_space,alloc_objects,inuse_spac,inuse_objects
计算方式:inuse = alloc - free
协程和系统线程采样
协程:记录所有用户发起且在运行中的协程(即入口非runtime开头的)runtime.main的调用栈信息
线程:记录程序创建所有系统线程的信息
阻塞操作和锁竞争采样
业务优化
流程:
建立服务性能评估手段
分析性能数据,定位性能瓶颈
重点优化项改造
优化效果验证
建立服务性能评估手段 之所以不用benchmark是因为时间服务逻辑比较复杂,希望从更高的层面分析服务的性能问题,同时机器在不同负载下的性能也会不同
评估手段建立后,产出一个服务的性能指标分析报告
有了服务优化前的性能报告和一些性能采样数据,我们可以进行性能瓶颈分析
业务服务常见的性能问题可能是使用的基础组件不规范
类似日志使用不归发,一部分是调试日志发布到线上,一部分是线上服务在不同的调用链路上数据有差别,测试场景日志还好,但是到了真实线上全景场景,会导致日志数量增加影响性能
另外常见的性能问题就是高并发场景的优化不足
重点优化项改造:
正确性实际基础!
性能优化的前提是保证正确性,使用在变动较大的性能优化上线之前,需要进行正确性验证,借助自动化手段保证优化后程序的正确性
优化效果验证:
用同样的数据对优化后的服务进行压测,同时压测并不能保证和线上表现完全一致,有时还要通过线上的表现在进行分析改进,是个长期的过程
基础库优化
适应范围更广,覆盖更多服务
AB 实验 SDK 的优化:
分析基础库核心逻辑和性能瓶颈
完善改造方案,按需获取,序列化协议优化
内部压测验证
推广业务服务落地验证
Go语言优化
适应范围最广,Go 服务都有收益
优化方式
优化内存分配策略
优化代码编译流程,生成更高效的程序
内部压测验证
推广业务服务落地验证
总结
性能评估要依靠数据,用实际的结果做决策
对于pprof工具,可以通过分析实际的程序,熟悉相关功能,理解好基本原理,后续能够更好的解决性能问题
在真正的服务性能调优流程中,链路会很长,重点是要保证正确性,不影响功能,同时定位好问题