Go语言pprof实战笔记(下) | 青训营

前言

今天来完成我们 pprof 工具实战的最后一个部分,小伙伴们跟着我一起来操作吧!

实战开始

先把炸弹程序运行起来再说

排查协程泄露

由于 GO 语言有垃圾回收 机制,所以一般不会出现内存泄露的情况,但是协程本身是有可能泄露的,也称协程失控,会导致内存泄露。

在浏览器打开 http://localhost:6060/debug/pprof/我们可以看到协程有106条

106条虽然不多,但是对于这样一个小程序来说还是有点异常,所以抱着不怕一万就怕万一的心态,我们需要排查一下是否真的存在异常。

同样使用go tool pprof http://localhost:6060/debug/pprof/goroutine来进入交互式的终端,然后使用toplist命令来排查问题

这次的问题比较隐晦,因为最顶上的调用不是自己写的函数,那么我们可以接着往下看,发现真正的问题所在是github.com/wolfogre/go-pprof-practice/animal/canidae/wolf.(*Wolf).Drink方法。

接下来使用list命令查看到底是什么问题

这里能看出来是创建了goroutine并且睡眠30秒才退出,但是貌似没有太大的问题,为什么会有这么多协程呢,我们根据路径提示来到源文件查看代码。

Go 复制代码
for i := 0; i < 10; i++ {
        go func() {
                time.Sleep(30 * time.Second)
        }()
}

发现居然是在for循环里面不停创建goroutine,这样一来原因就排查出来了,接下来把它优化掉继续下一个实践。

排查锁的争用

排查到现在,我们已经解决了程序占用资源的问题,不过这并不是性能优化的全部,因为还有其他原因也会导致程序性能下降,相信大家很容易地就能想到不合理的锁的争用问题,那么接下来我们就需要排查锁的争用。在浏览器界面我们也发现存在锁的争用

话不多说,直接运行go tool pprof http://localhost:6060/debug/pprof/mutex进入交互式终端,然后运行top命令

这里发现问题是由github.com/wolfogre/go-pprof-practice/animal/canidae/wolf.(*Wolf).Howl方法引起的,我们使用list命令查看一下具体什么问题。

需要注意一个问题,不是被标记的锁就是有问题的,我们需要根据实际业务去判断,这里代码看不完整,所以我们需要查看完整的源代码。

Go 复制代码
m := &sync.Mutex{}
m.Lock()
go func() {
        time.Sleep(time.Second)
        m.Unlock()
}()
m.Lock()

我们发现这里是由主协程上锁,然后在子协程里面做一些操作后释放,并且主协程在后面等待锁的释放,这在平时也许是正常的业务需要,但是子协程居然睡了一秒钟,并且没做什么有效的操作,所以应该优化掉。

排查阻塞操作

除了锁的争用会导致阻塞外,其他不合理的代码逻辑也是导致阻塞的原因之一,所以我们还要排查阻塞情况,在浏览器里面看到存在阻塞的情况。

运行go tool pprof http://localhost:6060/debug/pprof/block进入交互式终端

运行top命令

可以看到阻塞是由github.com/wolfogre/go-pprof-practice/animal/felidae/cat.(*Cat).Live方法引起的

接下来使用list命令探查实际代码

这里的情况和之前遇到的不一样,这里我们只看到了一堆方法调用,所以问题是在这一堆方法调用里面,那么到底是哪个有问题呢。结合之前top命令的结果,我们断定是github.com/wolfogre/go-pprof-practice/animal/felidae/cat.(*Cat).Pee方法有问题,所以输入list Pee回车查看具体代码。

通过top命令就能大概知道是因为channel使用不当导致阻塞,这里就更直观的把代码展示了出来,是因为time.After会阻塞当前线程一秒钟而不是睡眠一秒钟。嗯~有意思,优化掉。

总结

目前为止,本次pprof实战就结束了,把常用的操作都做了一遍,不过pprof还有很多需要我们去了解的地方,我们在以后学习的路上还要继续深入地学习。

相关推荐
CallBack8 个月前
Typora+PicGo+阿里云OSS搭建个人图床,纵享丝滑!
前端·青训营笔记
Taonce1 年前
站在Android开发者的角度认识MQTT - 源码篇
android·青训营笔记
AB_IN1 年前
打开抖音会发生什么 | 青训营
青训营笔记
monster1231 年前
结营感受(go) | 青训营
青训营笔记
翼同学1 年前
实践记录:使用Bcrypt进行密码安全性保护和验证 | 青训营
青训营笔记
hu1hu_1 年前
Git 的正确使用姿势与最佳实践(1) | 青训营
青训营笔记
星曈1 年前
详解前端框架中的设计模式 | 青训营
青训营笔记
tuxiaobei1 年前
文件上传漏洞 Upload-lab 实践(中)| 青训营
青训营笔记
yibao1 年前
高质量编程与性能调优实战 | 青训营
青训营笔记
小金先生SG1 年前
阿里云对象存储OSS使用| 青训营
青训营笔记