最近在做一个定时任务的项目,项目上线后。过段时间发现cpu不断飙高,10%,20%,30%,50%,70%,80%还再继续往上涨,吓得我赶紧下掉了项目。但是下掉了项目,就没有办法去排查cpu飙高的原因了,于是又重新上线。
庆幸的是,当cpu飙到90%多的时候,没有在继续上涨。趁着这个机会抓紧排查问题。排查问题从几个方面入手:
1、先去top 查看哪个进程占用cpu高,可以查询出来到底是自己的应用程序还是数据库又或者其他进程导致的。如果是java进程高,可以通过 top -Hp pid找到占比高的线程,然后转换成16进制,通过jstack堆栈找到java 应用程序。根据异常信息 定位程序中的哪行代码。然后再去看写的程序是否是占用cpu高的代码了,怎么核实这里就不在赘述了!可以去查询相关方面的博客。
2、如果不是java应用程序带来的cpu飙高,那就是mysql的访问或者其他了。经过一系列的排查,发现是mysql导致的飙高,cpu占比在700-800以上,服务器cpu内核才8cpu,说明此已经超出了服务器配置的内核数。由此可以得出,是数据库的运行导致cpu飙高,这就好办了。无非是两个方面导致,其一是运行的sql执行效率太慢,达到5-10秒以上才能查询出,这个肯定就是sql的索引问题导致的了。找到问题解决问题,果不其然,通过查询mysql运行的sql,发现一直在 执行一条相同的sql,state状态是query,时间在600-800甚至更高。于是,拿出此条sql。放在数据库中执行,发现效率真的特别慢,足足查询了接近10m才有结果。这仅仅是直接查询的数据库呀,可想而知,在程序里运行,那效率肯定还要大打折扣。因此该优化优化,该加索引加索引,my.cnf也对innodb引擎缓存池做了加大配置,一切就绪后。心中,顿时自豪感油然而生。。。。
3、mysql停止,重启。眼睛一动不动盯着cpu,cpu在慢慢的上涨,10%,20%,30%,50%,70%,一直涨到80%终于停止了,然后就一直 在10%-80%之间游荡。这个效果其实是有所好转的,最起码不会飙高到90甚至100大关了。但是80%这个占比还是太高了,继续排查,,,,问题
天空飘来五个字,那都不是事,
是事也就那一会 ,一会就完事!
4、接下来要讲的就是重点了,通过以上的优化配置文件,增加索引。的的确确解决了一些cpu占比高的问题,但是仍然还会时不时的飙到70-80%,这肯定事不行的。这就像一枚定时炸弹,说不定哪天就炸了。为啥还会有这样的问题呢?然后又继续排查问题,突然发现 mysql执行的进程中有一条sql在不断的交替出现,虽然执行时间就在几毫秒,但是几乎每次查询都能看到它的踪影。这说明此sql绝对是一条热点sql,它在很短的时间内频繁的被执行。这也就和自己的业务对上了,因为这个项目是一个定时任务,不间断的再跑数据,每次跑数据都会执行此条sql,所以定位+确定,导致cpu飙高的元凶就是这条sql的重复,频繁的被执行。
5、找到元凶就好办了,可以用很多的方法去搞定这个频繁执行sql的问题。我这边采用的是 通过redis缓存的方式来解决的,至于怎么实现,就不多说了。相信同为程序猿的你,一定知道。使用缓存后,效果明显,效果特别明显,cpu已经不会涨到70%了,最多到20%,这个占比还是蛮可以的,请允许我 骄傲5秒钟!
5!
4!
3!
2!
1!
最后截图,看效果(之前飙高到100%占比就不截图了,因为写这篇博客的时候已经解决,开始没想写,所以没有保存截图)
干我们这行的真不容易,总在积极又或者是被动的找BUG,甚至一个BUG让我们茶不思饭不想,几近崩溃。但是当问题解决后,我们会傻笑,会躁动,甚至会变得疯疯颠颠。只是因为,又解决了一个BUG。