系统中出现大量不可中断的进程和僵尸进程怎么办
短时应用的运行时间比较短,很难在top或者ps这里系统展示概要和进程快照中发现,需要使用记录事件的工具来配合诊断,比如execsnoop或者perf top
讲到cpu使用率的类型,除用户cpu之外,还包括系统cpu(上下文切换)、等待io的cpu(等待磁盘的响应)以及中断cpu(包括软中断和硬中断)等
--进程状态
当iowait升高时,进程很可能因为得不到硬件的响应,而长时间处于不可中断状态。从ps或者top中,可以发现都出d状态,也就是不可中断状态(uninterruptible sleep)
top,ps是最常用的查看进程状态的工具,top中s列表示进程的状态--R\D\Z\S\I等几个状态
--R是running或runnable,表示进程在cpu的就绪队列中,正在运行或正在等待运行
--D是disk sleep,不可中断状态睡眠(uninterruptible sleep)一般表示正在跟硬件交互,并且交互过程不允许被其他进程或中断打断
--Z是zombie,僵尸进程,也就是进程实际上已经结束了,但是父进程还没有回收它的资源
--S是interruptible sleep,可中断状态睡眠,表示因为等待某个事件而被系统挂起,当进程等待的事件发生,它会被唤醒并进入R状态
--I是idle,空闲状态,用在不可中断睡眠的内核线程上。要注意,D状态的进程会导致平均负载升高,I状态的进程却不会。
--T或者t,stoped或traced,表示进程处于暂停或者跟踪状态,向一个进程发送sigstop信号,它就会因响应这个信号变成暂停状态(stopped);再发送sigcont,进程会恢复
--X,表示进程已经消亡,不会在top或者ps中看到
--top命令,按1切换到cpu
如果系统或硬件发送了故障,进程可能会在不可中断状态保持很久,甚至导致系统中出现大量不可中断进程,需要注意,系统是不是出现了I/O等性能问题。
[root@mysqlhq ~]# yum install dstat -y
这里dstat是一个新的性能工具,吸收了vmstat、iostat、ifstat等工具的优点,可以同时观察系统的cpu、磁盘io、网络以及内存的使用情况
--不可中断状态,表示进程正在跟硬件交互,为了保护进程数据和硬件的一致性,系统不允许其他进程或中断打断这个进程。进程长时间处于不可中断状态,通常表示系统io性能问题。
--僵尸进程表示进程已经退出,但它的父进程还没有回收子进程占用的资源。短暂的僵尸状态通常不必理会,但进程长时间处于僵尸状态,就应该注意了,可能有应用程序没有正常处理子进程的退出。
--1 iowait太高,达到了系统cpu的个数
--iowait分析
[root@mysqlhq ~]#dstat 1 10 ##间隔1秒输出10组数据
You did not select any stats, using -cdngy by default.----total-cpu-usage---- -dsk/total- -net/total- ---paging-- ---system--usr sys idl wai hiq siq| read writ| recv send| in out |int csw1 0 99 0 0 0| 329k 133k| 0 0 | 0 0 | 202 249
0 0 100 0 0 0| 0 15k|4086B 842B| 0 0 | 176 225
0 0 100 0 0 0| 0 206k|3282B 362B| 0 0 | 182 258
0 0 100 0 0 0| 0 5120B|3341B 362B| 0 0 | 141 174
0 0 100 0 0 0| 0 0 |2946B 362B| 0 0 | 144 178
0 0 100 0 0 0| 0 10k|2142B 362B| 0 0 | 151 208
0 0 100 0 0 0| 0 15k|2640B 362B| 0 0 | 171 213
看read和writ,分析当iowait升高时,磁盘的读请求(read)或writ请求,很可能是磁盘的读或者写导致
根据top命令,观察D状态的进程
找到进程的pid,如是2171
##-d 展示io统计数据,-p进程号 间隔1秒输出3组数据
[root@mysqlhq ~]#pidstat -d -p 2171 1 3
Linux 3.10.0-514.ky3.kb3.x86_64 (mysqlhq) 06/11/2019 _x86_64_ (4CPU)04:51:13 PM UID PID kB_rd/s kB_wr/s kB_ccwr/s iodelay Command04:51:14 PM 1001 2171 0.00 0.00 0.00 0zabbix_agentd04:51:15 PM 1001 2171 0.00 0.00 0.00 0zabbix_agentd04:51:16 PM 1001 2171 0.00 0.00 0.00 0zabbix_agentd
Average:1001 2171 0.00 0.00 0.00 0 zabbix_agentd
kB_rd表示每秒读的KB数,kB_wr表示每秒写的KB数,iodelay表示io延迟,都是0表示此时没有任何的读写,说明问题不是出现在2171
用同样的方法分析其他D状态的进程
[root@mysqlhq ~]#pidstat -d 1 20 ##间隔1秒输出20组数据
Linux 3.10.0-514.ky3.kb3.x86_64 (mysqlhq) 06/11/2019 _x86_64_ (4CPU)04:55:37 PM UID PID kB_rd/s kB_wr/s kB_ccwr/s iodelay Command04:55:38 PM 1000 3093 0.00 15.84 0.00 0mysqld04:55:38 PM UID PID kB_rd/s kB_wr/s kB_ccwr/s iodelay Command04:55:39 PM 1000 3093 0.00 12.00 0.00 0 mysqld
观察发现,mysqld进程进行磁盘写,并且每秒写的数据是15kb,如果这个值很大,说明是该进程的问题
进程想要访问磁盘,就必须使用系统调用,所以接下来找出mysqld进程的系统调用
strace是最常用的跟踪进程系统调用的工具
[root@mysqlhq ~]#strace -p 1000
strace: attach: ptrace(PTRACE_ATTACH, ...): No such process[root@mysqlhq ~]#strace -p 3093
Process 3093attached
restart_syscall(<... resuming interrupted call ...>) = 1fcntl(31, F_GETFL) = 0x2(flags O_RDWR)
fcntl(31, F_SETFL, O_RDWR|O_NONBLOCK) = 0accept(31, {sa_family=AF_INET6, sin6_port=htons(37136), inet_pton(AF_INET6, "::ffff:127.0.0.1", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, [28]) = 133fcntl(31, F_SETFL, O_RDWR) = 0setsockopt(133, SOL_IP, IP_TOS, [8], 4) = 0setsockopt(133, SOL_TCP, TCP_NODELAY, [1], 4) = 0
如果执行失败
strace -p 6082
strace: attach: ptrace(PTRACE_SEIZE, 6082): Operation not permitted
一般遇到这种问题,先检查进程的状态是否正常
[root@mysqlhq ~]# ps aux|grep 6082
使用perf top查看
$ perf record -g
$ perf report
截图中的swapper是内核中的调度进程,可以先忽略掉
查看进程的系统调用
--僵尸进程
僵尸进程要解决,需要找他他们的根,也就是找出父进程,然后在父进程里解决
父进程的找法
# -a 表示输出命令行选项
# p 表PID
# s 表示指定进程的父进程
[root@mysqlhq ~]# pstree -aps 3093
找到父进程并解决
小结:
iowait高不一定代表io有性能瓶颈,当系统中只有io类型的进程在运行时,iowait也会很高,但实际上,磁盘的读写远没有达到性能瓶颈的程度。
碰到了iowait升高时,先使用dstat、pidstat等工具,确认是不是磁盘io的问题,然后再找那些进程导致了io
等待io的进程一般是不可中断状态,用ps命令找到D状态的进程,多为可疑进程,如果变成了僵尸进程,trace就不能直接分析进程的系统调用,这种情况下使用perf工具,类分析系统的cpu时钟事件,最终发现直接io问题。
僵尸进程的问题,使用pstree找出父进程,检查父进程的wait()/waitpid()的调用