找回密码
 立即注册
首页 业界区 业界 实操使用 go pprof 对生产环境进行性能分析(问题定位及 ...

实操使用 go pprof 对生产环境进行性能分析(问题定位及代码优化)

煅圆吧 昨天 20:14
简介

最近服务器有个小功能 go 进程 内存占用突然变得很高,正好使用 go pprof 实操进行性能分析排查解决
1.jpeg

这是个极小的服务,但是占用内存超过了 100MB,而且本身服务器内存就比较吃紧,因此尝试使用 pprof 进行性能分析,看看能不能优化到 50 MB 以内
关于 pprof 的使用教程,请移步文章:Golang 性能分析神器 pprof 详解与实践(图文教程)
接下来使用 go pprof 进行实操性能分析排查
一、开启 pprof

在项目启动时开启 pprof
导包:_ "net/http/pprof"
启动:http.ListenAndServe(":30552", nil)
参考代码如下
  1. import _ "net/http/pprof"
  2. func StartPprof() {
  3.     go func() {
  4.         logs.Info(http.ListenAndServe(":30552", nil))
  5.     }()
  6.     // 查看哪些函数占用内存比较多
  7.     // go tool pprof -http=localhost:8081 -seconds=10 http://0.0.0.0:30552/debug/pprof/heap # 内存堆栈分析
  8.     // go tool pprof -http=localhost:8081 -seconds=10 http://0.0.0.0:30552/debug/pprof/allocs # 内存分配分析
  9.     // 查看哪些函数占用耗时比较多
  10.     // go tool pprof -http=localhost:8081 -seconds=60 http://0.0.0.0:30552/debug/pprof/profile  # 耗时分析
  11.     // go tool pprof -http=localhost:8081 -seconds=60 http://0.0.0.0:30552/debug/pprof/goroutine  # 协程分析
  12.     // go tool pprof -http=localhost:8081 -seconds=10 http://0.0.0.0:30552/debug/pprof/block  # 阻塞分析
  13.     // go tool pprof -http=localhost:8081 -seconds=10 http://0.0.0.0:30552/debug/pprof/mutex  # 锁分析
  14. }
  15. func main(){
  16.   ....
  17.   StartPprof()
  18.   err = router.Run(address)
  19.     if err != nil {
  20.         panic(err)
  21.     }
  22.   ....
  23. }
复制代码
二、内存堆栈分析

分析哪些函数一直在占用内存
(一)问题分析
  1. go tool pprof -http=0.0.0.0:8081 http://0.0.0.0:30552/debug/pprof/heap
复制代码
这里我没有加 -seconds ,表示采样数据为:进程启动以来的总数据, 具体参数的使用:Golang 性能分析神器 pprof 详解与实践(图文教程)
浏览器会自动打开:0.0.0.0:8081/ui
如下图
2.jpeg

从图中可以看到:又红又粗的函数有:

  • webdav(*memFile) Write
通过箭头查看上下的调用链接,可以发现  swaggerFiles init 调用了此函数,通过搜索查看代码,分析服务中确实是使用了 gin-swagger,但是这个项目其实没必要
解决:注释掉这块代码

  • embedFS
同样通过箭头查看上下的调用链接,发现有个 base64Captcha 调用,这是因为服务使用了一个第三方的验证码生成的包 github.com/mojocn/base64Captcha
embedFS 很明显是加载了文件,通过查看代码发现确实是加载了 fonts 字体
3.jpeg

加载的字体大概有 5.9MB
解决:替换包,或者直接去掉验证码,我这里就选择一些比较轻量级的包做了替换
(二)总结

从火焰图上看,总体的内存堆栈不算太高,不过通过排查可以看到存在一些项目不需要的,但是有占用内存的函数/包,还是可以优化减少内存的占用,
通过以上的代码优化之后,重启并且观察一段时间后,内存确实稳定下降了一些
4.jpeg

三、内存分配分析

分析哪些函数一直在分配内存
内存分配比较多比较频繁的函数会导致内存突然飙高,内存分配不同于内存堆栈,内存堆栈是常驻内存,
具体区别请移步文章:Golang 性能分析神器 pprof 详解与实践(图文教程
(一)问题分析
  1. go tool pprof -http=0.0.0.0:8081 http://0.0.0.0:30552/debug/pprof/allocs
复制代码
浏览器会自动打开:0.0.0.0:8081/ui
如下图
5.jpeg

火焰图有点大,只截取了有问题的部分
从图中可以看到:又红又粗的函数有:

  • webdav(*memFile) Write + embedFS
    这里看不出来这两个函数的调用,我们可以切换为 top 视图(左上角菜单 view 中),就可以看到完整文件位置。
    解决:这个在上一步骤【内存堆栈分析】中就已经做了分析处理(注:代码发布后确实已修复)
  • DBUpdateCronTask
    这里很有可能是索引没有生效,导致锁全表了
    解决:通过对 update where 条件进行索引优化即可
  • go.Marshal
    这里用 go 标准库的 json 序列化操作,看起来分配内存也不算太多,不过我们可以优化为第三方包,性能更佳
    解决:全局替换包 encoding/json 为 github.com/json-iterator/go
  • fmt.Sprintf
通过排查代码,发现 FmtContent 中使用 fmt.Sprintf ,并且做了大量字符串的拼接,
解决:字符串拼接优化为使用 :strings.Builder
关于字符串拼接性能请移步文章:Go语言字符串拼接性能对比与最佳实践 - 深度优化指南
(二)总结

从火焰图上看,总体的内存分配不算太高,不过仍然有优化空间
通过以上的代码优化之后,重启并且观察一段时间后,内存成功下降到了 50MB 以内
6.jpeg

四、CPU 耗时分析

这里从 top 可以看出其实并没有什么 CPU 飙高的情况,不过既然都优化了,就顺便看看哪些函数在占用吧
(一)问题分析
  1. go tool pprof -http=0.0.0.0:8081 http://0.0.0.0:30552/debug/pprof/profile
复制代码
从火焰图上没看到什么耗时比较异常的函数
(二)总结

从 top 没看到CPU异常,火焰图也没有异常,如果存在异常,排查和优化的方法和前面内存的步骤是一样的
五、协程分析

分析程序开启的协程情况
(一)问题分析

浏览器直接打开以下命令
  1. http://0.0.0.0:30552/debug/pprof/goroutine?debug=1  # 协程总览
  2. http://0.0.0.0:30552/debug/pprof/goroutine?debug=2  # 协程详情
复制代码
界面展示说明如下:
7.jpeg

8.jpeg

从上面界面的数据进行分析

  • 协程总数量为:27(不算多,但是需要看下每个协程的堆栈情况)
  • 从 debug=2 的信息中查看每个协程的情况,发现其他都是正常的,有 main、 pprof 、cron、业务等启动的协程
    但是存在一个协程【44】:从堆栈上看,这并不是我服务所需的,通过查看这个堆栈定位到代码的地方,发现之前做链路追踪测试时确实导入这个  go.opentelemetry.io包
    但是实际没有任何功能作用
    解决:直接注释掉相关的代码和导包
(二)总结

通过界面先查询协程数量是不是太多,过多可能存在泄漏的情况,再通过 debug=2 界面查看每个协程的执行情况,是否非业务所需但是仍旧执行/阻塞,
然后根据堆栈定位代码,然后优化即可
总结

通过启动 pprof 服务,并且通过 go tool pprof 以及 pprof 内部提供的服务接口对 CPU、内存堆栈、内存分配、协程 等指标进行分析,定位问题函数,优化代码
定位问题函数时,优化后可以先本地做单元测试、压力测试、pprof 测试,具体步骤请查看文章:
go 如何进行 Benchmark 基准测试
Golang 性能分析神器 pprof 详解与实践(图文教程)
原文地址
实操使用 go pprof 对生产环境进行性能分析(问题定位及代码优化)

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册