线上故障主要会包括cpu、磁盘、内存以及网络问题,而大多数故障可能会包含不止一个层面的问题,所以进行排查时候尽量四个方面依次排查一遍。
同时例如jstack、jmap等工具也是不囿于一个方面的问题的,基本上出问题就是df、free、top 三连,然后依次jstack、jmap伺候,具体问题具体分析即可。
一般来讲我们首先会排查cpu方面的问题。cpu异常往往还是比较好定位的。原因包括业务逻辑问题(死循环)、频繁gc以及上下文切换过多。而最常见的往往是业务逻辑(或者框架逻辑)导致的,可以使用jstack来分析对应的堆栈情况。
我们先用ps命令找到对应进程的pid(如果你有好几个目标进程,可以先用top看一下哪个占用比较高)。
接着用top -H -p pid来找到cpu使用率比较高的一些线程
![](https://img-blog.csdnimg.cn/img_convert/efde0d61b79cfa773f060efe697fa36f.webp?x-oss-process=image/format,png)
然后将占用最高的pid转换为16进制printf '%x\n' pid得到nid
![](https://img-blog.csdnimg.cn/img_convert/5f2a1ab2a77a38c5e401c5fd5218fb18.webp?x-oss-process=image/format,png)
接着直接在jstack中找到相应的堆栈信息jstack pid |grep 'nid' -C5 –color
![](https://img-blog.csdnimg.cn/img_convert/6ccd64d5e8a055f3e8e97e75d7aa3783.webp?x-oss-process=image/format,png)
可以看到我们已经找到了nid为0x42的堆栈信息,接着只要仔细分析一番即可。
当然更常见的是我们对整个jstack文件进行分析,通常我们会比较关注WAITING和TIMED_WAITING的部分,BLOCKED就不用说了。我们可以使用命令cat jstack.log | grep "java.lang.Thread.State" | sort -nr | uniq -c来对jstack的状态有一个整体的把握,如果WAITING之类的特别多,那么多半是有问题啦。
![](https://img-blog.csdnimg.cn/img_convert/4e5e3f2d73749e84ec57a74bdee6c9de.png)
当然我们还是会使用jstack来分析问题,但有时候我们可以先确定下gc是不是太频繁,使用jstat -gc pid 1000命令来对gc分代变化情况进行观察,1000表示采样间隔(ms),S0C/S1C、S0U/S1U、EC/EU、OC/OU、MC/MU分别代表两个Survivor区、Eden区、老年代、元数据区的容量和使用量。YGC/YGT、FGC/FGCT、GCT则代表YoungGc、FullGc的耗时和次数以及总耗时。如果看到gc比较频繁,再针对gc方面做进一步分析。
![](https://img-blog.csdnimg.cn/img_convert/867b9932e32ea61c4cd6acb9a1cefefd.png)
针对频繁上下文问题,我们可以使用vmstat命令来进行查看
![](https://img-blog.csdnimg.cn/img_convert/93aa0224a44c8f92e291f0f8f8d54b57.png)
cs(context switch)一列则代表了上下文切换的次数。
如果我们希望对特定的pid进行监控那么可以使用 pidstat -w pid命令,cswch和nvcswch表示自愿及非自愿切换。
![](https://img-blog.csdnimg.cn/img_convert/90da0be3e737e889c3f528c92674609d.webp?x-oss-process=image/format,png)
磁盘问题和cpu一样是属于比较基础的。首先是磁盘空间方面,我们直接使用df -hl来查看文件系统状态
![](https://img-blog.csdnimg.cn/img_convert/5cb968ecae932aa1e507791259f7857d.webp?x-oss-process=image/format,png)
更多时候,磁盘问题还是性能上的问题。我们可以通过iostatiostat -d -k -x来进行分析
![](https://img-blog.csdnimg.cn/img_convert/4602180fa38408a1d21bc68ad7456056.webp?x-oss-process=image/format,png)
最后一列%util可以看到每块磁盘写入的程度,而rrqpm/s以及wrqm/s分别表示读写速度,一般就能帮助定位到具体哪块磁盘出现问题了。
另外我们还需要知道是哪个进程在进行读写,一般来说开发自己心里有数,或者用iotop命令来进行定位文件读写的来源。