这是我参与「第五届青训营」伴学笔记创作活动的第 4 天
一、本堂课重点内容
本节课程主要分为四个方面:
- Go 语言编码规范
- Go 语言性能优化建议
- 性能分析工具 pprof 的使用
- 性能调优实际案例
这篇文章主要介绍后两个方面,即性能分析工具 pprof 的使用和性能调优案例。
二、详细知识点介绍
1. 性能调优原则
- 要依靠数据而不是猜测。
- 要定位最大瓶颈而不是细枝末节。
- 不要过早优化。
- 不要过度优化。
2. 性能分析工具 pprof
-
功能简介
- 工具:
runtime/pprof,net/http/pprof - 采样:可以采样程序运行时的CPU、堆内存、goroutine、锁竞争等的使用数据。
- 展示:可以通过列表、火焰图、反汇编等视图去展示收集到的性能指标,方便分析。
- 分析:网页、可视化终端。
- 工具:
-
排查实战
-
运行代码后在浏览器中打开http://localhost:6060/debug/pprof/,可以看到程序运行采样数据和简单说明。
-
CPU问题排查
-
命令:
go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/cpu" -
使用
go tool pprof + 采样链接来启动采样,并下载采样信息的profile文件。-
eg.
go tool pprof "http://localhost:6060/debug/pprof/profile?seconds=10" -
输入
top命令,展示出CPU占用最高的函数,参数的意义如下:flat==cum,证明函数中没有调用其他函数;flat==0,证明函数中只有其他函数的调用。
-
输入
list xxx命令,根据指定的正则表达式查找代码行,并给出这段代码消耗的时间。 -
输入
web命令,生成调用关系图,并会显示每个节点的资源占用。
-
-
-
堆内存问题排查
-
命令:
go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/heap" -
SAMPLE之中的四个选项:
- inuse_space(默认):程序当前占用的内存大小。
- alloc_space:程序累积申请的内存大小。
- inuse_objects:程序当前持有对象数。
- alloc_objects:程序累积申请的对象数。
-
-
协程问题排查
- 命令:
go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/goroutine" - 火焰图由上到下表示调用顺序,每一块代表一个函数,越长代表占用CPU时间越长,支持点击块进行分析。
- 命令:
-
锁问题排查
- 命令:
go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/mutex"
- 命令:
-
阻塞问题排查
- 命令:
go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/block"
- 命令:
-
-
采样过程及原理
-
CPU采样
- 采样对象:函数调用和它们占用的时间。
- 采样率:100次/秒,固定值。
- 采样时间:从手动启动到手动结束。
- 过程:开始采样 -> 设定信号处理函数 -> 开启定时器。
-
堆内存采样
- 通过内存分配器在堆上分配和释放的内存,记录分配/释放的大小和数量。
- 采样率:每分配512KB记录一次。
- 采样时间:从程序运行开始到采样时。
-
协程和线程采样
- 记录用户发起且在运行中的协程的
runtime.main的调用栈信息。 - 记录程序创建的所有系统线程的信息。
- 记录用户发起且在运行中的协程的
-
阻塞采样
- 采样阻塞操作的次数和耗时。
- 采样率:阻塞耗时超过阈值的才会被记录。
-
锁竞争
- 采样争抢锁的次数和耗时。
- 采样率:只记录固定比例的锁操作。
-
三、实践练习例子 - 性能调优案例
-
业务服务优化
- 建立服务性能评估手段
- 分析性能数据并定位瓶颈
- 重点优化项改造
- 优化效果验证
-
基础库优化
-
分析基础库的核心逻辑和性能瓶颈
- 设计完善改造方案
- 数据按需获取
- 数据序列化协议优化
-
内部压测验证
-
推广业务服务落地验证
-
-
Go语言优化
- 优化内存分配策略
- 优化代码编译流程,生成更高效的程序
- 内部压测验证
- 推广业务服务落地验证