02. 性能调优实战
2.1 性能调优简介
性能调优原则 要依靠数据不是猜测 要定位最大瓶颈而不是细枝末节 不要过早优化(直到快出现瓶颈的时候再优化) 不要过度优化
2.2 性能分析工具pprof实战
说明 希望知道应用在什么地方耗费了多少CPU. Memory pprof是用于可视化和分析性能分析数据的工具
2.2.1 pprof功能简介
2.2.2pprof排查实战
搭建pprof实践项目 GitHub (来自Wolfogre )
前置准备(让人熟悉pprof代码的项目) 下载项目代码,能够编译运行 会占用1CPU核心和超过1GB的内存 项目提前埋入了一些炸弹代码,产生可观测的性能问题
浏览器查看指标
CPU
go tool pprof "[<http://localhost:6060/debug/pprof/profile?seconds=10>"](<http://localhost:6060/>)代表采样时间为10S,根据这个数据定位一下哪里可能的代码有问题
命令: topN 查看占用资源最多的函数
●Flat == Cum,函数中没有调用其他函数 ●Flat == 0,函数中只有其他函数的调用
命令: list 根据指定的正则表达式查找代码行,代码定位
命令: web 调用关系可视化
Heap-堆内存
cpu到0.2了,CPU的问题解决了
现在解决内存的问题
go tool pprof -http=: 8080”<http://local/host:6060/debug/pprof/heap>"
CPU降到了23.6MB
alloc_ objects: 程序累计申请的对象数 inuse_objects: 程序当前持有的对象数 alloc_ space: 程序累计申请的内存大小 inuse_ space: 程序当前占用的内存大小
alloc_ space
goroutine-协程 goroutine泄露也会导致内存泄露
go tool pprof -http= :8080"<http://localhost:6060/debug/pprof/goroutine>"
由上到下表示调用顺序 每一块代表个函数,越长代表占用CPU的时间更长 火焰图是动态的, 支持点击块进行分析
支持搜索,在Source视图下搜索wolf
注释问题代码后的结果
mutex-锁
go tool pprof -http=:8080 "<http://1ocalhost:6060/debug/pprof/mutex>"
block-阻塞
go tool pprof -http=:8080 "<http://1ocalhost:6060/debug/pprof/**block**>"
两个Block为什么只展示了一个
会丢弃掉4个节点(对于cum≤ 1.41S的情况)作为一个默认的过滤策略
真的想看可以去block链接
第二个阻塞操作是什么。黄色部分就是被隐藏掉的点
2.2.3pprof的采样过程和原理
CPU 采样对象:函数调用和它们占用的时间 采样率: 100次/秒,固定值 采样时间:从手动启动到手动结束
操作系统
- 每10ms向进程发送一次SIGPROF信号
进程
- 每次接收到SIGPROF会记录调用堆栈
写缓冲
- 每100ms读取已经记录的调用栈并写入输出流
Heap-堆内存 采样程序通过内存分配器在堆上分配和释放的内存,记录分配/释放的大小和数量 采样率:每分配512KB记录一次, 可在运行开头修改,1为每次分配均记录 采样时间:从程序运行开始到采样时 采样指标:alloc_ space, alloc_ objects, inuse_ space, inuse_objects 计算方式: inuse = alloc - free//已分配内存-空闲内存
Goroutine-协程& ThreadCreate-线程创建
Goroutine
- 记录所有用户发起且在运行中的goroutine (即入口非runtime开头的)
- runtime . main的调用栈信息
ThreadCreate
- 记录程序创建的所有系统线程的信息
Block-阻塞& Mutex-锁
阻塞操作
- 采样阻塞操作的次数和耗时
- 采样率:阻塞耗时超过阈值的才会被记录,1为每次阻塞均记录
锁竞争
- 采样争抢锁的次数和耗时
- 采样率:只记录固定比例的锁操作(比例是随机或者自己设置的) ,在比例内记录,不在丢弃,1为每次加锁均记录
小结 ●掌握常用pprof工具功能 ●灵活运用pprof工具分析解决性能问题 ●了解pprof的采样过程和工作原理