一、前言
线上问题排查是每一个程序员都应该具备的能力,这一篇文章将从问题分类、常用命令和工具、具体案例分析这几个方面进行说明。
二、常用工具和命令
常用:
jps -v
jstat -gc 118694 500 5
jmap -dump:live,format=b,file=dump.hprof 29170
jmap -heap 29170
jmap -histo:live 29170 | more
jmap -permstat 29170
jstack -l 29170 |more
jstack 31177 > /home/tengfei.fangtf/dump17
grep java.lang.Thread.State dump17 | awk '{print $2$3$4$5}'
| sort | uniq -c
关于命令的详细说明可以查看
三、问题分类以及处理策略
1、业务日志
如果应用系统出现异常,一般都会在业务日志中体现
统计当天业务日志中ERROR出现数量:egrep ERROR --color logname | wc -l ,如果错误数量过大,一般都是有问题的
查看日志中ERROR后10行具体报错:egrep -A 10 ERROR logname | less ,或 -C 10 查看ERROR前后10行日志
sed -n '/起始时间/,/结束时间/p' 日志文件
sed -n '/2018-12-06 00:00:00/,/2018-12-06 00:03:00/p' logname # 查询三分钟内的日志,后再跟grep 过滤相应关键字
sed -n '/2018-12-06 08:38:00/,$p' logname | less # 查询指定时间到当前日志
2.死锁
死锁原因是两个或者多个线程相互等待资源。现象通常是出现线程hung住。更严重会出现线程数暴涨,系统出现api alive报警等。查看死锁最好的方法就是分析当时的线程栈。
用到的命令:
jps -v
jstack -l pid
通过文中的例子启动了一个发生死锁的进程,执行上述命令,可以定位到引发死锁的代码。
3.OOM相关
发生OOM问题一般服务都会crash,业务日志会有OutOfMemoryError。
OOM一般都是出现了内存泄露,须要查看OOM时候的jvm堆的快照,假设配置了-XX:+HeapDumpOnOutOfMemoryError, 在发生OOM的时候会在-XX:HeapDumpPath生成堆的dump文件。结合MAT,能够对dump文件进行分析。查找出发生OOM的原因。
ps:
1、server的内存一般较大,所以要保证server的磁盘空间大于内存大小
2、另外手动dump堆快照。能够使用命令jmap -dump:format=b,file=file_name pid 或者kill -3 pid
常用命令:
$ jhat -J-Xmx512m dump.hprof
JVM配置:
-Xms10m -Xmx10m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=C:\Users\Administrator\Desktop
分析同样一个dump快照,MAT需要的额外内存比jhat要小的多的多,所以建议使用MAT来进行分析。
4.线程block、线程数暴涨
线程block问题通常是等待io、等待网络、等待监视器锁等造成,可能会导致请求超时、造成造成线程数暴涨导致系统502等。
假设出现这样的问题,主要是关注jstack 出来的BLOCKED、Waiting on condition、Waiting on monitor entry等状态信息。
假设大量线程在“waiting for monitor entry”:可能是一个全局锁堵塞住了大量线程。
假设短时间内打印的 thread dump 文件反映。随着时间流逝。waiting for monitor entry 的线程越来越多,没有降低的趋势,可能意味着某些线程在临界区里呆的时间太长了,以至于越来越多新线程迟迟无法进入临界区。
假设大量线程在“waiting on condition”:可能是它们又跑去获取第三方资源,迟迟获取不到Response,导致大量线程进入等待状态。
假设发现有大量的线程都处在 Wait on condition,从线程堆栈看,正等待网络读写,这可能是一个网络瓶颈的征兆,由于网络堵塞导致线程无法运行。
jstack -l pid |wc -l
jstack -l pid |grep "BLOCKED"|wc -l
jstack -l pid |grep "Waiting on condition"|wc -l
四、参考