go pprof性能调优工具


go pprof简介

一、性能调优原则

  1. 依靠数据而不是猜测,分析cpu/memory/网络/磁盘io/goroutine/mutex等具体数据情况,来分析问题。
  2. 重点先行,根据优先级,应该先优化最大的性能瓶颈处,而不是细枝末节。
  3. 不要过早优化,毕竟现在项目开发模式为–小步快走+反复迭代,API容易过时。
  4. 不要过度优化,同样是项目小步快走+反复迭代,该API可能过时,也可能大改,过度优化会增加系统复杂度,且不一定后期能用。

二、pprof

性能调优依靠数据而不是猜测,我们希望应用在什么地方消耗多少cpu/memory等,才能使我们的分析问题更加快速和准确。
go自带的pprof工具不仅可以知道应用在什么地方消耗多少cpu/memory等,而且还能可视化,提高分析速度。

1、pprof 功能简介

在这里插入图片描述

2、pprof 排查实战

前置工作

  • 搭建pprof实践项目,Wolfogre,该项目针对cpu/memory等埋了很多累,可以让性能问题更加明显。
  • 需要1CPU核心+1G内存。

在这里插入图片描述

a、CPU

  • 采样数据,go tool pprof "http://localhost:6060/debug/pprof/profile?seconds=10"

1.top,查看函数占用资源的情况。
在这里插入图片描述

指标含义
flat当前函数本身的执行耗时
flat%flat占cpu总时间的比例
sum%上面每一行flat%的累计和
cumflat+调用其它函数的耗时
cum%cum占cpu总时间的比例

可以发现,
Eat耗时最严重,所以重点分析Eat源代码;
当flat == 0时,说明函数中只有调用其它函数的代码;
当flat == cum时,说明该函数没有调用其它函数。

2.list,查找指定函数代码行耗时。
在这里插入图片描述
可以发现,
耗时代码为一个for循环。

3.web,调用关系可视化。
在这里插入图片描述

b、Heap

  • 采样数据,go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/heap",以web的形式展示,而不是终端。
  • top图
    在这里插入图片描述
  • source图
    在这里插入图片描述
  • sample
    在这里插入图片描述
指标含义
alloc_objects累计申请对象数
alloc_space累计申请内存大小
inuse_objects当前持有对象数
inuse_space当前占用内存大小

c、goroutine

  • goroutine泄露会导致内存泄露。
  • 采样数据,go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/goroutine"
    在这里插入图片描述

d、mutex

  • 采样,go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/mutex"
    在这里插入图片描述
    在这里插入图片描述

e、block

  • 采样,go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/block"
    在这里插入图片描述
    在这里插入图片描述

3、pprof 的采样过程和原理

a、cpu

指标内容
采样对象函数调用占用时间
采样时间手动启动到手动结束
采样率100次/秒,固定值

采样简要流程,开始采样 > 设定信号处理函数 > 开启定时器 > 采样 > 停止采样 > 取消信号处理函数 > 关闭定时器 > 结束采样。

doing
os每10s向进程发送一次sigprof信号
进程每接收到sigprof信号就记录调用堆栈
写缓冲每100ms读取记录的调用栈写入输出流

b、heap

依赖内存分配器的记录数据,记录分配/释放的对象数量和内存大小。

指标内容
采样时间从程序开始采样的到当前直至结束整个过程
采样指标alloc_space
alloc_objects
inuse_space
inuse_objects
采样率每分配512kb记录一次,可在运行开头修改,1为每次分配均记录
计算方式inuse = alloc - free

c、goroutine && threadCreate

  • goroutine,记录用户发起且在运行中的goroutine。Stop the world > 遍历allg切片 > 输出创建g的堆栈 > start the world.
  • threadCreate,记录程序创建的所有系统线程的信息。Stop the world > 遍历allm链表 > 输出创建m的堆栈 > start the world.

d、block && mutex

  • block,采样阻塞操作的次数和耗时,阻塞耗时超过阈值的才会被记录,1为每次阻塞均记录。
    在这里插入图片描述
  • mutex,采样争抢锁的次数和耗时,只记录固定比例的锁操作,1为每次加锁均记录。
    在这里插入图片描述

三、调优流程

对逻辑相对复杂的程序如何进行性能调优?优化哪些部分?调优流程如何?

  • 业务服务优化,具体业务,如点赞评论。
  • 基础库优化,如日志库。
  • Go语言优化。

1、业务优化

基本概念含义
服务能单独部署,承载一定功能的程序
依赖service A的功能实现依赖service B的响应结果,称service A 依赖service B
调用链路能支持一个接口请求的相关服务集合及相互之间的依赖关系
基础库公共的工具包、中间件

在这里插入图片描述

a、流程

  • 建立服务性能评估手段
角度内容
性能评估方式单独的benchmark无法满足复杂的逻辑分析
不同负载情况下表现会有差异
请求流量构造不同请求参数覆盖的逻辑不同
线上真实的流量情况
压测范围单机器压测
集群压测
性能数据采集单机性能数据
集群性能数据
  • 分析数据,定位性能瓶颈
    根据压测报告数据,结合火焰图,来定位性能瓶颈代码处。可能是使用库规范;高并发场景优化不足(无意义的同步操作);
  • 重点优化改造
    以正确性为基础,录制优化前的响应,对比优化后的响应。
  • 优化效果验证
    优化完成后,再次压测,根据压测报告的情况,才能发布上线,并关注线上运行是否有响应的优化效果。关注服务监控 > 逐步放量 > 收集性能数据。

注:进一步优化,则是看一个接口服务的整条链路,分析并优化。

2、基础库优化

  • 统计基础库使用占比
  • 分析基础库核心逻辑和性能瓶颈
  • 内部压测验证
  • 推广业务服务落地验证

3、go语言优化

  • 优化内存分配策略,如gc时的内存分配与回收,根据自己的业务运行统计数据来具体分析。
  • 优化代码编译流程,生成更高效的程序,函数内联,逃逸分析等。
  • 内部压测验证
  • 推广业务服务落地验证

注:go语言优化,接入简单,只需用新sdk编译并运行程序,且通用性强。

总结

  1. 性能优化原则,依靠数据而不是猜测。
  2. pprof工具使用,针对cpu/memory等数据进行采集,基于数据去可靠分析。
  3. 根据pprof采集到的数据,利用top/source/graph等方式灵活分析问题。
  4. pprof采用过程和原理。
  5. 性能调优要保证正确性,且先定位最大性能你瓶颈。

参考资料

[1] pprof实战代码
[2] pprof实战

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值