这是我参与「第五届青训营 」伴学笔记创作活动的第 12 天
性能调优
- 要依靠数据不是猜测
- 要定位最大瓶颈而不是细枝末节
- 不要过早优化
- 不要过度优化
性能分析工具-pprof
性能调优的核心是性能瓶颈的分析,对于 Go 应用程序,最方便的就是 pprof 工具。
pprof 功能简介
pprof 是用于可视化和分析性能分析数据的工具 可以知道应用在什么地方耗费了多少 CPU、Memory等运行指标
pprof 实践
首先搭建 pprof 实践项目,github.com/wolfogre/go… 项目提前埋入了一些存在性能问题的代码
排查实战
浏览器查看指标:在浏览器打开 http://localhost:6060/debug/pprof
排查 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 采样
- 堆内存采样
- 协程和系统线程采样
- 阻塞操作和锁竞争采样
性能调优案例
简介
介绍实际业务服务性能优化的案例以及逻辑相对复杂的程序如何性能调优。
基本概念:
-
服务:能单独部署,承载一定功能的程序
-
依赖:Service A 的功能实现依赖 Service B 的响应结果,称为 Service A 依赖 Service B
-
调用链路:能支持一个接口请求的相关服务集合及其相互之间的依赖关系
-
基础库:公共的工具包、中间件
业务优化
流程:
-
建立服务性能评估手段
- 服务性能评估方式:不使用 Benchmark,从更高的层面分析服务的性能问题
- 请求流量构造:模拟线上真实流量情况
- 压测范围:单机器压测和集群压测
- 性能数据采集:单机和集群
-
分析性能数据,定位性能瓶颈:通过 pprof 火焰图
- 使用库不规范
- 高并发场景优化不足
-
重点优化项改造
- 正确性是基础
- 响应数据 diff:线上请求数据录制回放、新旧逻辑接口数据 diff
-
优化效果验证
- 重复压测验证
- 上线评估优化效果:关注服务监控、逐步放量、收集性能数据
-
进一步优化,服务整体链路分析
- 规范上游服务调用接口,明确场景需求
- 分析链路,通过业务流程优化提升服务性能
基础库优化
基础库的优化适用范围更广,比如在实际业务服务中,为了评估某些功能上线后的效果,经常需要进行 AB 实验,看看不同策略对核心指标的影响。
- AB 实验 SDK 的优化
- 分析基础库核心逻辑和性能瓶颈
- 完善改造方案
- 按需获取
- 序列化协议优化
- 内部压测验证
- 推广业务服务落地验证
Go 语言优化
适用范围最广的优化就是针对 Go 本身进行的优化,会优化编译和运行时的内存分配策略,构建更高效的 Go 发行版本。
编译器和运行时优化:
- 优化内存分配策略
- 优化代码编译流程,生成更高效的程序
- 内部压测验证
- 推广业务服务落地验证
优点:
- 接入简单,只需要调整编译配置
- 通用性强
总结
本文主要总结Go语言常见的性能调优工具与方法以及其在工程项目中的应用,无论在大的项目当中还是小的项目之内,高效率高性能是必不可少的。