问题描述:
最近在测试环境的服务器上,无意中发现cpu持续飙高。最高的时候达到了200%经过反复重启无效之后,决定挖掘深层次的原因
通过top命令打印出消耗cpu的pid,如图
通过ps -mp 24597 -o THREAD,tid,time,找出进程中cpu占用率最高的tid
通过 jstack -F tid >> tid.log打印出该进程下的线程信息
在文件中可以看到一行怪异的信息
从线程信息中,可以看到,似乎是这个线程调用某一个dubbo服务的时候,线程阻塞了,持续消耗cpu
排查之后没有结论。。。
-------------------------------------------------------------------------分割线----------------------------------------------------------------------------------------
换一种排查方式。。。
用 vmstat 1 10 命令看一下可能存在的问题
下图中可以发现in和cs值有些异常
in:表示每秒cpu中断的次数
cs:表示每秒产生的 上下文切换数。我们调用函数,就要进行上下文切换;线程间的切换,也要进程上下文切换。
这个值越小越好,太大了,要考虑调低线程或者进程的数目。
我们做大并发测试时,选择web服务器的进程可以从进程或者线程的峰值一直下调,压测,直到cs到一个比较小的值,这个进程和线程数就是比较合适的值。
另外,每次调用系统函数,我们的代码就会进入内核空间,导致上下文切换,这个很耗资源,要尽量避免频繁调用。
上下文切换次数过多表示你的CPU大部分浪费在上下文切换,导致CPU不能充分利用和正常工作。
in和cs值越大,表示内核消耗的cpu越多
接下来我们看一下关键进程的上下文切换数
先找出消耗cpu最大的进程
top -Hp 24597
pid =24619
查看一下该进程的上下文切换数
pidstat -p 24619 -w 1 10
- PID:进程id
- Cswch/s:每秒主动任务上下文切换数量
- Nvcswch/s:每秒被动任务上下文切换数量
- Command:命令名
可以看出该进程每秒都在被动的切换上下文,而且数量很大
用pstack查看一下线程日志
似乎是sleep的问题,未完待续。。。。
-------------------------------------------------------------------------分割线----------------------------------------------------------------------------------------
跨度有点久了,现在终于找到了问题根源
通过线程分析工具,打印出了占用cpu最高的方法调用
bash show-busy-java-threads
原来是target目录下dubbo文件的权限有问题,因为该文件不是当期用户权限,所以读取的时候产生了死循环,导致cpu飙高
把这个文件的权限改成当前用户,然后重启一下tomcat。cpu就降下来了