Tomcat监控与排错思路
# TOMCAT监控
监控tomcat实际就是监控tomcat的jvm状态。
# 命令行命令
# jps
jps [option]
- 查看java进程,jps命令实际就是java的ps(process status)命令。- 我们一般可以通过Tomcat目录路径去过滤出指定Tomcat实例。
# 参数
-l
- 输出主类的名称,如果进程执行的是JAR包,则输出JAR文件的路径。-v
- 输出JAVA虚拟机进程启动时的JVM参数。-m
- 输出JAVA虚拟机进程启动时传递给主类main()方法的参数。
# jmap
jmap [option] <pid>
- 显示指定JAVA进程的JVM中各依赖占用的内存。# 参数
-dump:format=b,file=/root/jvm.bin
- 导出JVM内存样本,之后可以通过MAT工具分析。
# jstat
jstat [option] <pid>
- 显示指定JAVA进程的JVM中状态信息。# 参数
-gc
- 展示JVM垃圾回收信息。
# jstack
jstack <pid>
- 显示指定JAVA进程的JVM中的线程信息。
# 脚本查看状态
- https://github.com/oldratlee/useful-scripts
# JMX远程监控
JMXREMOTE是用于JAVA用于远程调试或监控的扩展功能。
# 配置方式
vim ./tomcat/bin/setenv.sh
- 在setenv.bat或setenv.sh文件中配置- 如果tomcat的bin目录下没有这个文件,可以手动创建。
- setenv.bat或setenv.sh是tomcat的变量通用文件,里面的变量会被daemon.sh和startup.sh等启动器引用。
CATALINA_OPTS="$CATALINA_OPTS \ #启动JMXREMOTE功能 -Dcom.sun.management.jmxremote \ # 指定JMX端口 -Dcom.sun.management.jmxremote.port=12345 \ # 是否开启认证功能 -Dcom.sun.management.jmxremote.authenticate=false \ # 是否使用SSL加密 -Dcom.sun.management.jmxremote.ssl=false \ # 监听的网卡(为了安全需要设置为内网网卡地址) -Djava.rmi.server.hostname=192.168.10.11"
1
2
3
4
5
6
7
8
9
10
11
# 查看方式
- 需要在Windows安装JDK,通过Windows JDK工具访问JMX。
- 启动jconsole程序:
C:\Program Files\Java\jdk-19\bin\jconsole.exe
- 然后输入
[IP:端口]
进行远程连接即可。
# TOMCAT故障排除
# Tomcat开机自启动失败
- 原因
- 开机时或定时任务脚本运行时,无法识别到自定义的PATH环境变量,没有java相关路径,导致开机时tomcat启动失败。
- 解决方法
- 在开机自启脚本或定时任务脚本的开头使用加载环境变量脚本命令
. /etc/profile
。
- 在开机自启脚本或定时任务脚本的开头使用加载环境变量脚本命令
# Tomcat负载高
# 排查流程
- 通过
ps aux/top
命令找到占用资源高的Tomcat进程ID。 - 然后通过
top -Hp <pid>
命令检查Tomcat进程的线程信息,线程的CPU资源占用,然后得到线程占用高的线程ID。 - 然后通过jstack命令查看进程的线程信息,并根据线程ID筛选出有问题的线程,并记录该线程信息。
- 然后通过jmap命令导出JVM内存信息,做一个内存取样,之后可以通过mat工具分析。
- 然后结合Tomcat日志和开发分析原因。
# 实际命令
# 查找到CPU占用高的Tomcat线程
top
# 根据进程ID查看CPU占用高的线程ID
top -Hp <pid>
# 因为jstack中的线程ID是十六进制的,所以需要将得到的负载高的线程ID转换成十六进制,然后转成小写才能过滤出来
# 查看Tomcat线程的所有进程信息并过滤出占用高的线程信息,主要看java.lang.Thread.State状态是否是正常,比如:RUNNABLE
jstack <pid> | grep -A20 "nid=0x`echo 'obase=16;TID' | bc | tr [A-Z] [a-z]`"
# 以上可以直接使用show_busy_java_threads.sh脚本查看线程状态
# 导出JVM内存样本,之后可以通过MAT工具分析
jmap -dump:format=b,file=/root/jvm.bin <pid>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14