前言:线上服务器在访问量大,或者其他特殊情况下,可能会出现CPU占用高,或者服务直接不停FULL GC导致服务器卡顿甚至挂掉的情况,针对不同情况,根本原因也各有差异,前段时间我们公司服务器就出现了大量redis链接超时,乍一看可能是网络抖动或者redis配置问题,但是深究之下发现其实是服务cpu负载特别高导致的,今天就总结一下各种服务器问题解决思路
CPU占用率高
针对CPU占用太高的问题,我们可以先用top命令看下是哪个进程导致的,找到对应pid后,可以接着用 top -H -p pid 查询到cpu使用率比较高的线程
找到对应占用cpu较高的线程pid后,将占用最高的pid转换为16进制
printf '%x\n' pid
得到nid,接着在jstack查找对应堆栈信息就可以看到对应线程在搞什么
jstack pid |grep 'nid'
注:此时jstack命令如果报错
16206: Unable to open socket file: target process not responding or HotSpot VM not loaded
The -F option can be used when the target process is not responding
当确认当前用户有jstack log的操作权限后,还是有这个报错,可以参考这篇文章:
https://bxoon.blog.csdn.net/article/details/111881528
OOM
jvm内存泄漏,可以用jmap命令导出dump文件,使用mat(Eclipse Memory Analysis Tools)对堆内存进行分析,看是那部分对象占用导致内存溢出的
dump命令:
jmap -dump:format=b,file=filename pid
有时发生OOM的时候我们无法实时输入上述命令,可以通过给java启动命令添加参数,来实现内存溢出时,自动生成dump文件,可以第一时间保存罪证,方便后续排查,如下
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/tmp/dump/
GC
有时我们不确定服务cpu占用高是否是由于频繁的GC导致的,所以最好可以给jvm加一个gc日志的配置,方便我们实时去定位问题,GC日志配置:
-XX:+PrintGC
-XX:+PrintGCDetails
-XX:+PrintHeapAtGC
-XX:+PrintTenuringDistribution
-XX:+PrintGCTimeStamps
-XX:+PrintGCDateStamps
-Xloggc:/opt/log/java-GC.log
-XX:+UseGCLogFileRotation
-XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=256M
具体GC 日志分析可参考以下文章:https://www.jianshu.com/p/0ed902739aa0