系统中出现大量不可中断的进程和僵尸进程怎么办

系统中出现大量不可中断的进程和僵尸进程怎么办

短时应用的运行时间比较短,很难在top或者ps这里系统展示概要和进程快照中发现,需要使用记录事件的工具来配合诊断,比如execsnoop或者perf top

讲到cpu使用率的类型,除用户cpu之外,还包括系统cpu(上下文切换)、等待iocpu(等待磁盘的响应)以及中断cpu(包括软中断和硬中断)等

--进程状态

iowait升高时,进程很可能因为得不到硬件的响应,而长时间处于不可中断状态。从ps或者top中,可以发现都出d状态,也就是不可中断状态(uninterruptible sleep

topps是最常用的查看进程状态的工具,tops列表示进程的状态--R\D\Z\S\I等几个状态

--Rrunningrunnable,表示进程在cpu的就绪队列中,正在运行或正在等待运行

--Ddisk sleep,不可中断状态睡眠(uninterruptible sleep)一般表示正在跟硬件交互,并且交互过程不允许被其他进程或中断打断

--Zzombie,僵尸进程,也就是进程实际上已经结束了,但是父进程还没有回收它的资源

--Sinterruptible sleep,可中断状态睡眠,表示因为等待某个事件而被系统挂起,当进程等待的事件发生,它会被唤醒并进入R状态

--Iidle,空闲状态,用在不可中断睡眠的内核线程上。要注意,D状态的进程会导致平均负载升高,I状态的进程却不会。

--T或者tstopedtraced,表示进程处于暂停或者跟踪状态,向一个进程发送sigstop信号,它就会因响应这个信号变成暂停状态(stopped);再发送sigcont,进程会恢复

--X,表示进程已经消亡,不会在top或者ps中看到

--top命令,按1切换到cpu

如果系统或硬件发送了故障,进程可能会在不可中断状态保持很久,甚至导致系统中出现大量不可中断进程,需要注意,系统是不是出现了I/O等性能问题。

[root@mysqlhq ~]# yum install dstat -y

这里dstat是一个新的性能工具,吸收了vmstatiostatifstat等工具的优点,可以同时观察系统的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   csw 
  1   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 

readwrit,分析当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_    (4 CPU)
04:51:13 PM   UID       PID   kB_rd/s   kB_wr/s kB_ccwr/s iodelay  Command
04:51:14 PM  1001      2171      0.00      0.00      0.00       0  zabbix_agentd
04:51:15 PM  1001      2171      0.00      0.00      0.00       0  zabbix_agentd
04:51:16 PM  1001      2171      0.00      0.00      0.00       0  zabbix_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_    (4 CPU)
04:55:37 PM   UID       PID   kB_rd/s   kB_wr/s kB_ccwr/s iodelay  Command
04:55:38 PM  1000      3093      0.00     15.84      0.00       0  mysqld

04:55:38 PM   UID       PID   kB_rd/s   kB_wr/s kB_ccwr/s iodelay  Command
04: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 3093 attached
restart_syscall(<... resuming interrupted call ...>) = 1
fcntl(31, F_GETFL)                      = 0x2 (flags O_RDWR)
fcntl(31, F_SETFL, O_RDWR|O_NONBLOCK)   = 0
accept(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]) = 133
fcntl(31, F_SETFL, O_RDWR)              = 0
setsockopt(133, SOL_IP, IP_TOS, [8], 4) = 0
setsockopt(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升高时,先使用dstatpidstat等工具,确认是不是磁盘io的问题,然后再找那些进程导致了io

等待io的进程一般是不可中断状态,用ps命令找到D状态的进程,多为可疑进程,如果变成了僵尸进程,trace就不能直接分析进程的系统调用,这种情况下使用perf工具,类分析系统的cpu时钟事件,最终发现直接io问题。

僵尸进程的问题,使用pstree找出父进程,检查父进程的wait()/waitpid()的调用

posted @ 2019-06-11 17:33  春困秋乏夏打盹  阅读(1484)  评论(0编辑  收藏  举报