性能调优实战笔记 | 青训营

120 阅读3分钟

前言

在软件开发的过程中,我们常常追求卓越的性能和优化。然而,优化并非盲目猜测,而是依靠数据和事实的指引。正如在我们的项目中,我们不仅要依赖直观的感觉,更要依赖详实的数据来定位问题所在。这种数据驱动的方法可以让我们更加准确地找到问题的根本原因,而不是陷入细枝末节的纠结。

优化的过程中,我们要有明确的目标,即定位最大的瓶颈点。通过专注于主要的性能瓶颈,我们可以更高效地改善应用的性能。火焰图、性能分析工具等帮助我们深入了解应用的行为,找到真正影响性能的关键路径。

优化需要权衡时间、资源和效益。过度优化可能导致代码变得难以维护,甚至可能引入新的问题。我们应该在明确的数据支持下,有针对性地进行优化,不盲目地在每个细节上投入过多精力。

因此,在我们的项目中,让我们坚持依靠数据而不是猜测,定位最大瓶颈而不是细枝末节。同时,我们要保持冷静头脑,不要急于过早和过度优化。

性能分析工具 pprof

在Gin 框架中集成 pprof

  1. 导入 pprof 包: 首先,你需要在代码中导入 pprof 包。
  1. 注册 pprof 路由: 在 Gin 的路由中注册 pprof 的路由,以便访问各种性能分析数据。你可以在任何需要的地方注册,比如在 Gin 的路由初始化函数中

屏幕截图 2023-08-05 171056.png

使用 pprof 进行性能分析

启动项目之后 可以通过 Web 页面来查看指标情况

以下是一些常用的性能指标以及对应的命令行参数:

  1. 查看CPU使用情况:

    go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/profile"
    
  2. 查看内存分配情况:

    go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/heap"
    
  3. 查看阻塞概况:

    go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/block"
    
  4. 查看goroutine信息:

    go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/goroutine"
    
  5. 查看线程创建概况:

    go tool pprof -http=:8080 "http://localhost:6060/debug/pprof/threadcreate"
    

如果打开对应的页面发现报错Could not execute dot; may need to install graphviz. 则需要安装 graphviz 并配置好环境变量
下图是我的项目中 内存 分配情况的调用关系图一部分和火焰图

屏幕截图 2023-08-05 151800.png

屏幕截图 2023-08-05 153208.png

发现 sensitive 和 initFilter 相关的代码占用内存较大,这部分的代码是我的项目中进行敏感词过滤的部分,要将敏感词库文件加载入内存中,因此要耗费大量内存

下面使用命令行进行性能分析
启动项目后命令行输入

go tool pprof http://localhost:6060/debug/pprof/heap

进入交互界面,输入 top 可查看排名在前的内存占用

屏幕截图 2023-08-05 154544.png 发现 seneitive 占用的内存较多
我在 main.go 文件删除初始化敏感词过滤器相关的代码后再查看内存使用情况,发现已经明显降低,如下图

屏幕截图 2023-08-05 154943.png 在图纸可见 GetRedisDB 的函数占用较高的内存,我用list命令查看这部分函数的内容

屏幕截图 2023-08-05 155100.png 我原本的代码中每次使用 redis 都调用一次这个函数,导致产生大量的redis连接

屏幕截图 2023-08-05 155459.png 我改成如下代码后,复用了一个 redis.Client

屏幕截图 2023-08-05 155434.png 再运行项目查看一下

屏幕截图 2023-08-05 155407.png 原本的 GetRedisDB 所占用的内存已经退出 TOP10 至此内存占用从原来的 11932.68kB 减小到了 2573.51 kB

总结

以上是使用 pprof 进行性能优化和分析的基本步骤