在 Linux 环境下定位 Tomcat 慢请求(响应慢、卡顿),通常需要从 系统层 → JVM 层 → Tomcat 层 → 应用层 逐步排查。下面是一套实战可用的定位思路和方法。
top
htop
vmstat 1
iostat -x 1
重点关注:
free -h
df -h
ping tomcat_ip
telnet ip 8080
curl -w "@curl-format.txt" http://ip:8080/url
curl-format 示例:
time_namelookup: %{time_namelookup}
time_connect: %{time_connect}
time_starttransfer: %{time_starttransfer}
time_total: %{time_total}
Tomcat access_log:
tail -f catalina.out
tail -f localhost_access_log.*.txt
重点关注:
%D 或 %T)推荐 access_log 配置:
pattern="%h %l %u %t "%r" %s %b %D"
%D:请求耗时(毫秒)查看 server.xml:
<Connector port="8080"
maxThreads="200"
acceptCount="100" />
线程打满表现:
查看线程数:
ps -T -p <tomcat_pid> | wc -l
ps -ef | grep tomcat
jps -l
jstat -gcutil <pid> 1000
重点看:
FGC / FGCT 是否很高O (Old区) 是否接近 100%开启 GC 日志(推荐):
-XX:+PrintGCDetails
-XX:+PrintGCDateStamps
-Xloggc:/logs/gc.log
jstack <pid> > thread.log
分析重点:
BLOCKEDWAITING例如:
"scheduler-1" #23 prio=5
java.lang.Thread.State: WAITING
at java.lang.Object.wait
at com.xxx.dao.query()
top -Hp <pid>
把高 CPU 线程 ID 转成 16 进制:
printf "%x\n" <tid>
再到 jstack 中搜索。
slow_query_log = ON
long_query_time = 1
在代码中增加:
# 1. 抓 access_log 慢请求
grep '耗时>1000' localhost_access_log.*
# 2. 抓线程栈
jstack pid > t1.log
sleep 5
jstack pid > t2.log
# 3. 对比线程状态
trace com.xxx.controller.* *
如果你愿意,可以把:
发给我,我可以帮你做针对性分析。