常见的几种问题:
- swap高
- load高
- cpu使用率
- 磁盘报警
几种case可能独立出现,也可能有因果关系的导致先后、同时出现。
说一下一般的排查、处理思路
CPU使用率高
这个查起来很方便,直接使用top命令,查看CPU使用最高的进程,查找该进程中CPU占用最高的线程,再进行具体排查。
对于web应用来说,CPU使用率变高,很大可能是因为程序的问题CPU过高一般是有如下原因造成的:
java代码中存在死循环导致CPU过高
系统存在不恰当的代码, 尽管没有死循环, 但仍然CPU过高。
JNI中有死循环代码,
堆内存设置太小造成的频繁GC. (堆内存设置过小, 或者存在内存泄漏)
32位JDK下, 堆内存设置太大造成的频繁GC.
JDK自身存在死循环的Bug.
CPU过高问题定位的第一步就是要找到CPU高消耗的线程。这个过程可以写成脚本,自动找出web服务中CPU消耗最高的N个线程:
1 |
|
替换上面脚本中的java环境变量以及web项目路径:1
2JAVA_HOME=你的java路径
WEB_HOME=你的web项目所在路径
假设你的tomcat进程是用tomcat账户启动的,用法如下:1
2sudo chmod 755 ./slow_stack.sh
sudo -utomcat ./slow_stack.sh 进程pid 使用率最高的count个线程
load高
load高与cpu和io的相关性很大。
load值的算法
load 的1分钟、5分钟、14分钟的average值,代表了这几分钟内,运行中+可运行等待调度的进程数量的平均值,也就是CPU使用队列的长度的统计信息
与CPU使用率的区别
CPU使用率是程序在运行期间实时占用的CPU百分比。进程是非CPU密集型、以及CPU上下文切换等情况下,CPU使用率是不高的。因此可见,CPU使用率与CPU负载load并没有必然联系。
但往往CPU使用率的提升是导致load增高的一个主要原因
CPU对load的影响
理论上来说,单核CPU的load如果到了1,就说明cpu的负载能力被充分使用了,大于1的时候,就有进程在等待CPU了。所以N核的CPU,load满载的时候是1×N。可以参考理解Linux系统负荷
由此可以看出,当出现上面的CPU消耗过高的情况,就可能导致等待、堆积的进程变多,导致load增高。
IO对load的影响
根据上面对load和cpu的分析可以看出,若是有过多的IO等待,也会造成CPU使用队列堆积,load增高的现象。
磁盘读写请求过多就会导致大量I/O等待。 cpu的工作效率要高于磁盘,而进程在cpu上面运行需要访问磁盘文件,这个时候cpu会向内核发起调用文件的请求,让内核去磁盘取文件,这个时候会切换到其他进程或者空闲,这个任务就会转换为不可中断睡眠状态。当这种读写请求过多就会导致不可中断睡眠状态的进程过多,从而导致负载高,cpu低的情况。
排查问题的时候可以重点排查IO状况是否正常、不可中断睡眠状态的线程是否过多。
绑核
特定情况下,会发现cpu使用率低,idle比较高、io没有异常,但是load一直很高的情况。这种情况可能是出现了绑核。
当你使用top命令时,cpu的使用状况、idle值是平均值,如果展开看每个cpu的使用的状况,也许会发现很多进程都绑到了同一个核上,其他内核一直空闲,而这一个内核因为任务堆积导致load增高
load异常变高的的场景,排查问题的方向始终来源于load值本身的算法,load增高必然是因为任务过多导致cpu队列堆积,以此为思路就可以展开排查,从cpu使用率、io、绑核等常见原因入手。
swap增高
swap高的原因,直接原因就是内存不够用,导致内存中的数据换出到磁盘上,而这样同时会导致写磁盘的IO增高
swap增高通常的原因可以检查一下进程是否有内存泄露。
磁盘报警
磁盘报警目前常见的基本两类:磁盘被写满、inode用尽
磁盘写满
问题很直接,直接查找一下系统中持续增长的大文件,删减就ok。删除方法:线上大日志文件的删除。不过这背后的原因需要深究。
一般来说,web服务器出现这样的情况,是因为日志文件过大导致的,所以需要思考一下日志输出是否合理、日志文件的压缩时机是否合适。
inode用尽
inode用尽通常是因为小文件过多导致将有限的inode资源用尽,所以可能磁盘使用率并不高
使用df -ih查看使用情况:1
2
3
4
5
6
7
8[sage.wang@machine /path]$ df -ih
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/vda2 640K 41K 600K 7% /
tmpfs 1000K 4 1000K 1% /dev/shm
/dev/vda1 50K 39 50K 1% /boot
/dev/vda6 63K 1.4K 62K 3% /home
/dev/vda7 3.9M 3.8M 20k 99% /home/xxx
/dev/vda5 256K 1.6K 255K 1% /var
可以看到/home/xxx
下面的inode使用了99%,接下来就是看一下具体哪个目录里使用的最多了,按照上面的目录一层一层的找下,查找的方法用下面的脚本:1
2
3
4
5
6
7
8
9[sage.wang@machine /home/xxx/www/webserver]$ for i in ./*; do echo $i; find $i | wc -l; done
./conf
9
./logs
2365048904
./webapps
2349
./work
9
这里就能看出来,比较多的文件其实是log文件和webapps下面的类文件
PS:上面的文件个数是我随便写的
关键用法:
for i in ./*; do echo $i; find $i | wc -l; done
查找当前目录下的目录有多少个文件