后台工程师和运维工程师经常遇到这样的问题,机器的CPU突然增加。
CPU增高可能会让程序的响应变慢,甚至把整个程序挂住,从而引起流量雪崩,严重影响用户体验。好好的代码,怎么突然CPU就增加了呢?最近虚拟币这么火,不会是有同事利用公司的服务器偷偷进行挖矿吧!假如这个时候,你的Leader突然让你定位这个问题,你要怎么办?难顶!写了几年的ifelse,都不知道如何排查CPU问题。今天我们来讲一个Linux的性能监控神器:Perf。
Perf
我们先讲一讲这个原理,假如让你来排查一个程序里面,哪些方法更加消耗CPU,你会怎么做。我们很难侵入程序,对每一次调用进行统计,那么我们能否换一个思路,我们每隔一段时间,去看看CPU在干啥。假如我们一秒钟去CPU那里观察100次,发现有70次都是在执行A方法,那么,我们可以近似地认为,CPU有70%的时间,都在执行A方法,那么A方法可能就是最消耗CPU的操作。
Perf Top
我们可以执行perf top命令,查看当前CPU的运行情况。如下图所示,我们可以看到,a.out这个任务占据了CPU的绝大部资源,其中,我们观察到,func_c占用了39.97%的CPU资源,func_b也是。假如我们希望优化,那么如果能够在这两个大头上有所建树,那么应该能够取得事半功倍的效果。
这里需要注意的一点是,虽然我们在使用perf top命令时,能够使用-p参数指定对应的进程ID,但是在现网上,并不推荐这么做。非常有可能挂住原有进程,对线上用户造成影响。
火焰图
可能你会觉得Perf的看到的结果并不能直观地反馈系统的开销,也不够厉害,那么有没有更厉害的方法呢?能够让你看起来更加厉害。我们可以在Github上面下载FlameGraph,可以对perf的数据进行采集,画出来的图片就像熊熊燃烧的火焰,我们称之为火焰图。
那么问题来了,这么高端的火焰图怎么看呢?
上面是一个简化的火焰图,假如总共有A到E五个不同的方法,那么我们应该优先看哪一个?有一个最简单的原则,就是减去上层之后,剩余部分,就是当前的方法的开销。例如Func_A虽然很长,但是减去Func_B与Func_C之后,剩余并无多少。在上图,最值得我们关注的,是Func_B与Func_D,对这个两个方法进行重点分析,能够让我们事半功倍。
总结
以往我工作遇到一些同事,遇到CPU暴涨,第一时间就是看代码,虽然有时候一些死循环、死锁可以发现,但是这种效率仍然非常低下。Perf是一个简单而又有效的工具,能够让我们快速定位问题。有了这个工具,我们带着目的再去看代码,可以更加高效解决问题。