在日常工作中常常需要应对突发性的线上问题排查工作,面对线上问题排查具备良好的排查思维逻辑是解决问题的重要条件之一,结合本人看到的一篇推文以及自身工作中的经验再次记录一下线上问题排查的指南
网络部分
一般情况下我们出现问题的时候大部分都是接受到预警消息或者邮件,这时候我们第一时间应该做的就是登陆日志系统查询当时的是否出现
connection timed out
如果有这样的问题那就赶快去找网络组的提一个issue吧
JVM部分
- 关于jvm内存泄漏的问题一般上来就是一个
top free df
看看cpu的占用情况,一般来说非大量计算性进程是不会出现cpu高于300%的一旦高于300%那么一定是有问题的 - 随后在执行
jstat -gc pid [interval]
命令看一下GC的情况,如果发现full GC太过频繁那么没跑了内存泄漏无疑了 - 随即保留犯罪现场
jstack pid > jstack.log
保存线程栈,jmap -dump:format=b,file=heap.log pid
保存堆现场,然后可以先重启服务,来保证服务短暂恢复正常
文件分析部分
到这里问题并没有解决,接下来我们要找到问题的发生的根源
# 查看栈内线程数
grep 'java.lang.Thread.State' jstack.log | wc -l
# 查看线程状态
grep -A 1 'java.lang.Thread.State' jstack.log | grep -v 'java.lang.Thread.State' | sort | uniq -c |sort -n
下载dump文件,其实这一步是有点头疼的,因为一般我们线上设置的堆内存都在好几个G所以下载起来是比较困难的,所以这里我们用到一个命令来压缩一下文件gzip xxx.log
这里我看有部分博主提出修改他的压缩率,其实目前默认的6级压缩其实已经是空间和时间的较为平衡的点了。
MAT 是分析 Java 堆内存的利器,使用它打开我们的堆文件(将文件后缀改为 .hprof), 它会提示我们要分析的种类,对于这次分析,选择 memory leak suspect。通过MAT生成的结果即可得到具体内存泄漏的对象。看到源代码分析代码即可