Tomcat重启负载高问题定位
2015-10-26 19:43
393 查看
最近线上服务器遇到一个问题,当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左右,就会回落,效果明显。
每次重启的时候,都收到大量报警短信,此问题必须要解决了。
后来排查占用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左右,就会回落,效果明显。
相关文章推荐
- java-模拟tomcat服务器
- i-jetty环境搭配与编译
- 实现单Tomcat多Server配置
- 生产环境下的Tomcat配置
- Linux部署Tomcat服务器
- jenkins------结合maven将svn项目自动部署到tomcat下
- 如何搞定tomcat这只喵~
- C#线程间不能调用剪切板的解决方法
- 我的服务器SQL2000的sqlserver占用了90%的cpu,怎么查是那个库?
- MySQL服务器进程CPU占用100%的解决方法
- C#线程同步的三类情景分析
- C#获取CPU编号的方法
- C#获取进程或线程相关信息的方法
- C#停止线程的方法
- C#子线程更新UI控件的方法实例总结
- C#线程队列用法实例分析
- 使用MySQL Slow Log来解决MySQL CPU占用高的问题
- 笔记本下什么是迅驰处理器(cpu)相关资料第1/2页
- C++使用CriticalSection实现线程同步实例