线上故障主要包括CPU、磁盘、内存、网络 问题,大多数都是多种问题并存。
CPU 问题
cpu问题 一般包括 死循环、频繁GC、上下文切换。
死循环
-
找出 占用cpu 高的 pid
#查看cpu 核心数:cpu cores cat /proc/cpuinfo # c - 显示整个命令行而不只是显示命令名 # 命令运行中,可以通过 内部命令 控制显示方式 # -P 按 cpu 占用率 排序 top -c
-
找出 进程 内的 占用高的 线程
# 命令运行中,可以通过 内部命令 控制显示方式 # -P 按 cpu 占用率 排序 top -c -H -p pid命令展示的pid ,可转换成十六进制的线程nid(操作系统映射的线程id)。
printf '0x%x\n' pidps -T p pid也可以看 进程内 的线程信息 -
查看JVM 栈信息
jstack 787 |grep -e 'nid=<nid>' -C 5 --color如果说系统慢,那么要特别关注Blocked,Waiting on condition 如果说系统的cpu耗的高,那么肯定是线程执行有死循环,那么此时要关注下Runable状态。
-
频繁GC
jstat -gc 787
| S0C/S1C | S0U/S1U | EC/EU | OC/OU | MC/MU |
|---|---|---|---|---|
| Survivor区容量/Survivor区容量 | Survivor区使用量/Survivor区使用量 | Eden区容量/使用量 | 老年代容量/使用量 | 元数据区容量/使用量 |
YGC/YGT、FGC/FGCT、GCT则代表YoungGc、FullGc的耗时和次数以及总耗时。
| YGC/YGCT | FGC/FGCT | GCT |
|---|---|---|
| 年轻代 次数/使用时间(s) | old代全gc次数/使用时间(s) | gc 总时间(s) |
- gc 排查
-
上下文切换
使用 vmstat 查看系统 状况
如果我们希望对特定的pid进行监控那么可以使用 pidstat -w pid命令,cswch和nvcswch表示自愿及非自愿切换。
磁盘
可以使用 df -hl 查看磁盘使用量
还可以使用 iostat -d -k -x 查看性能信息
rrqm/s: 每秒进行 merge 的读操作数目.即 delta(rmerge)/s
wrqm/s: 每秒进行 merge 的写操作数目.即 delta(wmerge)/s
%util: 一秒中有百分之多少的时间用于 I/O
如果%util接近100%,说明产生的I/O请求太多,I/O系统已经满负荷
idle小于70% IO压力就较大了,一般读取速度有较多的wait。
iotop命令来进行定位文件读写的来源。
iotop -o -P
内存
OOM 问题
-
Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native thread可以通过修改
/etc/security/limits.conf中的nofile和nproc来增大os对线程的限制 -
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space堆的内存占用已经达到-Xmx设置的最大值
-
Caused by: java.lang.OutOfMemoryError: Meta space元数据区的内存占用已经达到
XX:MaxMetaspaceSize设置的最大值
Stack Overflow
Exception in thread "main" java.lang.StackOverflowError
栈内存 大于Xss值
jmap 定位
jmap -dump:format=b,file=dump.hprof <pid>
通过 -XX:+HeapDumpOnOutOfMemoryError 启动 参数,在 OOM 时 保存 dump 文件
通过 mat(Eclipse Memory Analysis Tools) 查看 dump 出来的文件
通过 pstreee -p pid |wc -l ,查看 进程内的 线程总数