tomcat 要运行依赖于 JDK,tomcat 服务器的 CPU 使用率过高, 大多都是因为部署的 web 程序的问题.
一, 现象描述
在一次线上环境, 前台访问页面的速度越来越慢, 从浏览器 F12 中看到发出的请求都是 pengding 的状态.
二, 排查过程
我这里 tomcat 部署在 Linux 环境中. 下面的排查过程均在 Linux 下进行.
1, 排查后台服务
查看 tomcat 的后台日志, 发现日志正常打印, 未发现异常信息; 把要执行的 SQL 复制出来, 放到 MySQL 的客户端执行, 发现 sql 运行正常且查询速度正常.
通过上面的排查发现要访问的功能正常, 排除是当前功能造成的原因.
2, 排查服务器
1, 找出耗 CPU 的进程
使用 top 命令查看特定用户 (user1) 的内存, CPU 及各进程的信息,
top -u user1
使用上面的命令, 可以看到下面的信息,
从上面可以看到存在一个 java 的进程, 由于我这里没有其他的 java 相关的进程, 这里可以判断为 tomcat 的进程, 这里可以看到 PID 为 47787, 通过 %CPU,%MEM 分别表示 CPU, 内存的使用率, 由于我这里问题已经解决, 所以看到 CPU 的使用率已经下来了, 异常情况下可以是超过 100% 的数值.
这样我们就可以找出使用 CPU 过高的进程.
还可以通过下面的命令来快速找到 java 进程,
jps
使用 jps 命令可以快速找到 java 进程的 PID, 如下图
这里可以看出 PID 为 47787 为 tomcat 进程. 还可以使用下面的命令,
ps -ef |grep tomcat
上面的命令打印出下方的信息,
回到正题, 上面使用 top 命令找到了 CPU 过高的进程.
2, 找出耗 CPU 的线程
在上一步中找到了耗 CPU 的进程, 下面要找到耗 CPU 的线程. 我们知道一个进程中可以有多个线程, 进程是线程的集合.
使用下面的命令找到耗 CPU 的线程,
top -Hp 47787
上面的 "47787" 即上一步中找到进程 id, 意思就是找出该进程下的线程信息. 如下图,
从上图中可以看到该进程下的线程信息, 由于我这里已经正常了, 所以未看到 CPU 过高的线程, 上图中的 PID 这里代表的是线程 ID. 假如 47875 这个线程的 %CPU 使用过高,
下面把该线程 ID, 转化为 16 进制.
printf "%x\n" 47875
从上图可以看出 47875 的 16 进制为 "bb03".
上面, 通过进程 ID, 找到了耗 CPU 的线程 ID, 并且转化为了 16 进制.
3, 从 JVM 堆栈中查找线程信息
我们获得了耗时较高的线程 ID, 下面通过 JVM 的堆栈信息找到线程信息, 那么如何获得 JVM 的堆栈信息那, 使用下面的命令
jstack 47787> ./jvm.log
上面的 "47787" 代表的是上面的进程 ID, 打印出 47787 进程的堆栈信息, 保存在当前目录的 jvm.log 文件中.
下面从 jvm.log 文件中找到上面的线程信息,
grep -rn bb03 ~/jvm.log -A 100
找到下面的信息,
从上面可以看到是一些线程信息, 那要怎么去排查那, 可以通过上图红框中的状态为 RUNNABLE 的线程信息, 即为正在运行的线程, 从这里可以找到相关的信息, 最终解决问题.
三, 总结
CPU 使用率过高, 多数是因为线程无法终止或出现死循环等原因, 需具体问题具体分析.
来源: https://www.cnblogs.com/teach/p/12660541.html