线上应用故障排查思路
# 线上应用故障排查思路
线上应用故障,通常可以分为四个部分入手排查,也可能故障不是一方面到导致,所以我们根据问题,一个个去切入排查。
首先登录机器,使用 top
命令观察机器的整体情况,显示如下
# CPU 使用异常
当应用出现响应慢时,一般可能是CPU
使用异常,例如上下文频繁切换、频繁GC、死循环等。
# 线程死循环
使用top
命令查看机器 CPU 使用情况,如果出现单个进程CPU
占用过高,则进行下一步操作,如果未发现CPU
占用过高的情况则估计非死循环导致CPU使用异常。
使用 top命令后按H
键后将会按照CPU
使用情况从高到低排序,找到占用CPU
较高的进程对应的PID ,如下图占用最高的PID为3629272
使用命令打印该进程下占用CPU
较高的线程信息
top -H -p PID
输入后得到该进程下占用CPU
较多的线程,可以看见PID为3629289
**注意:**在线程堆文件中,是 16 进制表示的,所以要将该 PID 转为 16 进制
printf '%x\n' 3629289
转换结果为 3760e9
接着可以直接在该进程的线程运行信息中查找该 ID,其中PID为目标进程的PID,nid为线程PID转换后成16 进制后的数字
jstack PID | grep 'nid' -C 10
不直接查看也可以先导出该进程的线程信息快照,然后分析该文件,导出时加上-l
参数会增加显示关于锁的附加信息,用于检查线程死锁
jstack -l 3629272 >> TestDeadCycle.jstack.log
在文件中查找的结果,显示正在运行的代码位置在TestDeadCycle类第6行,我们可以去观察这附近的代码,继续排查问题。
对于生成了线程快照文件,可以分析文件得到线程的状态,如果大量线程处于WAITING
或者TIMED_WAITING
或者BLOCKED
那肯定是有问题的。
统计线程状态命令
cat TestDeadCycle.jstack.log | grep "java.lang.Thread.State" | sort -nr | uniq -c
# 频繁 GC 导致 CPU 过高
频繁的GC
会带来较大的性能损失,也会消耗大量的CPU
资源,查看目标线程的 GC,采样间隔为 1000ms 命令如下
jstat -gc PID 1000
# 频繁上下文切换
频繁切换上下文,不一定会导致CPU
使用率过高,但是会导致CPU
执行代码的时间变少,导致程序运行效率降低,系统响应速度变慢。
使用vmstat命令查看上下文切换信息,其中cs(context switch)列表示上下文切换的次数。
vmstat PID
root@VM-20-5-ubuntu:~# vmstat 3629272
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 0 0 164560 90072 1453320 0 0 1 16 1 2 0 0 99 0 0
2
3
4
5