下面想跟大家分享一下个人的一些排障思路。
一.常用的linux自带工具
1. 首先是top命令,查看操作系统的整体情况
关键参数:
Load average:系统平均负载,分别表示1分钟的平均负载为0.18,5分钟的平均负载为0.20,15分钟的平均负载为0.09。解释一下,比如说“15分钟内的平均负载为0.09”表示从现在到15分钟之前的系统的任务队列的平均长度为0.09,也就是说在这15分钟内平均只有0.09个任务在执行,表示系统负载在一个非常低的程度。一般而言,单CPU的话,该参数小于等于1是最优情况,N个CPU的话,该参数也最好是小于等于N;
Mem:内存,从图中可看出总共16G内存,其中13544344K已经被使用,2789812K free(未分配),593500K的buffers(缓冲区)和2595464Kcached(缓存)。其中有个误区,很多人以为系统当前还可以使用的只有free的内存,其实真实的剩余内存应该包括free+buffers+cached。
SWAP:交换分区。操作系统会从磁盘划出一块空间作为交换分区(有点像windows的虚拟内存),当free+buffers+cached的内存不足时,一部分内存的数据会存放至交换分区。由于硬盘的速度远远低于内存,所以当SWAP开始被频繁使用后,会明显感觉到系统变得很慢。所以当SWAP分区的值不断增大时就是操作系统告诉我们内存不足的最明显的信号。
%CPU:某应用程序的以单个CPU计算的CPU使用率,有时候会有200%,300%的情况(有些进程会同时使用到几个CPU),一般在应用服务器上看到某个进程的%CPU长时间保持50%以上,就应该重点关注一下。(tips:top -H -p pid 可以查看某个进程的所有线程的情况,有些情况有奇数);
2. iostat -kx 查看磁盘io
关键参数:
rKB/s:每秒从磁盘读的KB数
wKB/s:每秒往磁盘些的KB数
%util:磁盘的带宽利用率,如果长时间处于50%以上,就应该重点关注
3. netstat -antp 查看当前建立的网络连接
一般要结合其他命令来使用
netstat -antp | grep 某 pid | wc -l 查看某进程的连接总数
netstat -antp | grep 某 IP:某端口 | wc -l 查看某ip端口的连接情况,如netstat -antp | grep 172.25.132.31:1521 | wc -l 可以看到本机一共向132.31这台数据库(1521是oracle数据库默认端口)建立了201条连接
如netstat -antp | grep 172.25.132.31:1521 | grep 2139 | wc -l可以看到2139进程一共向132.31这台数据库建立了30条连接
其他工具还有
1). lsof列出当前系统打开文件的工具
2). ulimit启动进程所占用的资源,经常使用来查看操作系统对进程的各种限制
3). free一个更友好查看内存的工具
二、Java JDK带的管理工具
1. jstack 打印java各个线程的堆栈内容
jstack -l 某pid
生产实例:前置代码中调用getLocalHost方法等待时间较长,导致交易缓慢
另一个例子:数据库操作的堆栈信息
2. jstat
关键参数
S0,S1,E,O:java堆内存里面各个区域的使用比,特别是E,O在70%以上可能就要关注一下是否有内存溢出等问题了。
YGC,FGC:JVM新/老生代垃圾回收的次数,如果FGC的次数在不断增加,那肯定是某个区域内存不够了,需要进行配置JVM参数,或者是内存泄漏了。
3. jmap打印java程序中所有对象的数据,主要用于定位内存溢出问题
jmap -dump:format=b,file=文件名 某pid 可以将java堆内存中所有的对象数据输出到文件里面,然后用MAT工具进行分析
jmap -histo某pid 查看堆内存(histogram)中的对象数量,大小
最后推荐一本书《深入理解java虚拟机 jvm高级特性与最佳实践》,对JVM的内存区域划分,内存管理,垃圾收集,常见异常与排查进行了深入浅出的讲解