Tomcat重启负载高问题定位

来源:互联网 发布:蚂蚁分类信息5.8 源码 编辑:程序博客网 时间:2024/04/30 13:21

最近线上服务器遇到一个问题,当tomcat重启的时候,机器(8核)的cpu和负载飙升明显,负载严重时飙升到100,然后缓慢回落……

每次重启的时候,都收到大量报警短信,此问题必须要解决了。

后来排查占用cpu最多的线程时,打出线程堆栈信息发现,C2 CompilerThread 线程占用cpu比较多。


在网上发现这篇文章 :http://hellojava.info/?p=195

前几天又碰到了一个应用启动时load比较高的现象,而且更悲惨的是过了比较久都没恢复,本来按经验来说应该是能恢复才对,降低启动时进入的流量又是OK的,直接就说明碰到了超级难解的启动时Java性能比较差的问题。

首先尝试了下加上-XX:+TieredCompilation,期望借助多层编译来缓解这个问题,重启了后发现没什么太明显的缓解,悲催…(这种方案我也没有试,到底有没有用也不好说)

话说除了这个办法,也没别的什么办法,于是再次看了下启动后进入流量就比较大的时候cpu的消耗状况(perf top),看到的信息如下:
14353.00 18.6% _ZN17InvocationCounter9set_carryEv libjvm.so
14050.00 18.2% _ZN18InterpreterRuntime26frequency_counter_overflowEP10JavaThreadPh libjvm.so
13543.00 17.6% _ZN9CodeCache9find_blobEPv libjvm.so

从上面的信息可以看到,cpu的消耗基本都在执行次数的统计、解释执行和从code cache里找编译的方法这些上面,这基本说明了应用此时大部分的CPU主要是耗在了从解释执行–>编译执行的阶段,而悲催的是这个一直降不下去。

后来只好是重启,并且降低了进入的流量,等到了应用rt恢复到了一个正常值后,继续增大流量,才基本稳定下来了。

由这个现象可见,如果单机的qps比较高的话,很有可能会出现无法重启的现象,那就悲催大了…这个问题绝对是目前Java的硬伤之一(另外的一个大硬伤:大内存场景下GC及内存问题排查)。

解决方案如下:http://hellojava.info/?p=201


尝试加一个-XX:CICompilerCount参数来试试,这个值默认是2,也就是说2个c2的编译线程来进行编译,我改为了cpu core数的一半,重新启动了下效果明显比以前好了很多,load还是会冲高,不过下降的很快,因此说明这个参数是work的。

既然启动的时候访问量比较大,如果一直耗在解释执行时状况其实也不会多好,确实不如多拿几个线程来做编译,加快达到高峰性能的速度,而到达了高峰后,多这几个编译线程对整体并不会有什么影响。


综合以上,经测试,重启的时候负载也会有飙升,但是只会飙升到2左右,就会回落,效果明显。


0 0
原创粉丝点击