转载于https://www.toudo.cn/article/8
前言
Java 语言是当前互联网应用最为广泛的语言,作为一名程序猿掌握 Java 服务线上问题排查思路并能够熟练排查问题常用工具/命令/平台是每一个 Java 程序猿进阶必须掌握的实战技能。
常见问题
总的来说线上问题可以分为两大类:系统异常、业务异常。系统异常不外乎,CPU、内存、磁盘、网络四个方面,例如常见问题CPU使用率峰值突然飙高、内存溢出、磁盘满了、网络流量异常、带宽满了等。
一般我们采用排除法、解决问题。当系统业务异常、首先我们想到的是查看业务日志。
问题定位
查看业务日志
常用的查看日志命令
tail -100f 文件名 动态查看日志文件最后100行
如果日志文件出现大量连接异常等日志记录、那么直接去排查链接异常问题即可。
切忌vim直接打开较大的日志文件,由于会直接载入到内存的
系统问题
如果业务日志正常、那么需要排查系统异常了
CPU占用情况分析
top 查看 CPU占用率
ps -ef | grep java 查看服务进程id
top -H p 进程id
(以下图片只是介绍怎么使用,实际CPU并不高)
将占比高的线程PID换算成16进制,去堆栈日志找对应的线程堆栈信息,分析问题就可以了
内存使用情况分析
free -h 根据合适的单位显示内存使用情况
有时我们需要持续的观察内存的状况,此时可以使用 -s 选项并指定间隔的秒数:
free -h -s 3
输出内容介绍
下面先解释一下输出的内容:
Mem 行(第二行)是内存的使用情况。
Swap 行(第三行)是交换空间的使用情况。
total 列显示系统总的可用物理内存和交换空间大小。
used 列显示已经被使用的物理内存和交换空间。
free 列显示还有多少物理内存和交换空间可用使用。
shared 列显示被共享使用的物理内存大小。
buff/cache 列显示被 buffer 和 cache 使用的物理内存大小。
available 列显示还可以被应用程序使用的物理内存大小。
磁盘使用分析
df -h 查看磁盘使用情况
磁盘满了很多时候会连带引起系统服务不可用等问题
网络分析
dstat 命令可以集成了 vmstat、iostat、netstat 等等工具能完成的任务。
dstat -c cpu情况
-d 磁盘读写
-n 网络状况
-l 显示系统负载
-m 显示形同内存状况
-p 显示系统进程信息
-r 显示系统IO情况
JVM问题
java虚拟机相关的问题一般多是下面几种问题:gc时间过长、OOM、死锁、线程block、线程数暴涨等问题。一般通过下面几个工具都能定位出问题。
jps命令
jps 用于输出当前用户启动的所有进程 ID,当线上发现故障或者问题时,能够利用 jps 快速定位对应的 Java 进程 ID。
jps -l -m 参数用于输出主启动类的完整路径
或者使用
ps -ef | grep java
我们也能快速获取 Tomcat 服务的进程 id。
jmap 命令
jmap(Memory Map for Java) 命令用于生成堆转储快照dump文件
XX:HeapDumpOnOutOfMemoryError参数,可以在虚拟机发生OOM的时候自动生成堆的dump文件
jmap -heap pid 输出当前进程JVM堆新生代、老年代、持久代等请情况,GC使用的算法等信息
jmap -histo:live {pid} | head -n 10 输出当前进程内存中所有对象包含的大小
jmap -dump:format=b,file=/usr/local/logs/gc/dump.hprof {pid} 以二进制输出档当前内存的堆情况,然后可以导入MAT等工具进行
jmap -heap pid
jmap -histo:live {pid} | head -n 10
jstack 命令
printf '%x\n' tid --> 10进制至16进制线程ID(navtive线程) %d 10进制
jstack pid | grep tid -C 30 --color
ps -mp 8278 -o THREAD,tid,time | head -n 40
(1) 利用 top 命令可以查出占 CPU 最高的线程 pid
top -H p {pid}
获取到【pid】14235
printf '%x\n' 14235
获取到16进制线程id 379b
jstack pid | grep tid -C 30 --color
利用 jstack 打印出 Java 线程调用栈信息
jinfo 命令
查看某个JVM参数值
jinfo -flag ReservedCodeCacheSize 28461
jinfo -flag MaxPermSize 28461
jstat 命令
jstat -gc pid
jstat -gcutil `pgrep -u admin java`
内存分析工具 MAT
什么是MAT
MAT(Memory Analyzer Tool),一个基于 Eclipse 的内存分析工具,是一个快速、功能丰富的 JAVA heap 分析工具,它可以帮助我们查找内存泄漏和减少内存消耗。使用内存分析工具从众多的对象中进行分析,快速的计算出在内存中对象的占用大小,看看是谁阻止了垃圾收集器的回收工作,并可以通过报表直观的查看到可能造成这种结果的对象。
右侧的饼图显示当前快照中最大的对象。单击工具栏上的柱状图,可以查看当前堆的类信息,包括类的对象数量、浅堆(Shallow heap)、深堆(Retained Heap)。
经过分析就能找到哪块代码有问题了。