ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

07-案例篇:系统中出现大量不可中断进程和僵尸进程怎么办?(上)

2021-11-15 16:01:06  阅读:149  来源: 互联网

标签:状态 07 0.0 top 进程 root CPU 僵尸






引子

当碰到无法解释的CPU使用率问题时,先要检查一下是不是短时应用在捣鬼
短时应用的运行时间比较短,很难在top或者ps这类展示系统概要和进程快照的工具中发现,
需要使用记录事件的工具来配合诊断,比如execsnoop或者perf top

CPU使用率的类型,除了用户CPU之外
它还包括系统CPU(比如上下文切换)、等待I/O的CPU(比如等待磁盘的响应)以及中断CPU(包括软中断和硬中断)等

在前面上下文切换的章节中,分析了系统CPU使用率高的问题
剩下的等待I/O的CPU使用率(以下简称为iowait)升高,也是最常见的一个服务器性能问题

本章和下一章主要讲一个多进程I/O的案例




进程状态

当iowait升高时,进程很可能因为得不到硬件的响应,而长时间处于不可中断状态
从ps或者top命令的输出中,可以发现它们都处于D状态,也就是不可中断状态(Uninterruptible Sleep)


进程有哪些状态?
top和ps是最常用的查看进程状态的工具

# top
[root@local_sa_192-168-1-6 ~]# top
PID   USER PR NI VIRT  RES  SHR   S %CPU %MEM TIME+ COMMAND
28961 root 20 0  43816 3148 4040  R 3.2 0.0 0:00.01 top
620   root 20 0  37280 33676 908  D 0.3 0.4 0:00.01 app
1     root 20 0  160072 9416 6752 S 0.0 0.1 0:37.64 systemd
1896  root 20 0  0      0    0    Z 0.0 0.0 0:00.00 devapp
2     root 20 0  0      0    0    S 0.0 0.0 0:00.10 kthreadd
4     root 0 -20 0      0    0    I 0.0 0.0 0:00.00 kworker/0:0H
6     root 0 -20 0      0    0    I 0.0 0.0 0:00.00 mm_percpu_wq
7     root 20 0  0      0    0    S 0.0 0.0 0:06.37 ksoftirqd/0

S列(也就是Status列)表示进程的状态

R是Running或Runnable的缩写,表示进程在CPU的就绪队列中,正在运行或者正在等待运行

D是Disk Sleep的缩写,也就是不可中断状态睡眠(Uninterruptible Sleep)
一般表示进程正在跟硬件交互,并且交互过程不允许被其他进程或中断打断

Z是Zombie的缩写,它表示僵尸进程,也就是进程实际上已经结束了,但是父进程还没有回收它的资源(比如进程的描述符、PID等)

S是Interruptible Sleep的缩写,也就是可中断状态睡眠,表示进程因为等待某个事件而被系统挂起
当进程等待的事件发生时,它会被唤醒并进入R状态

I是Idle的缩写,也就是空闲状态,用在不可中断睡眠的内核线程上。硬件交互导致的不可中断进程用D表示
但对某些内核线程来说,它们有可能实际上并没有任何负载,用Idle正是为了区分这种情况
要注意,D状态的进程会导致平均负载升高,I状态的进程却不会

T或者t,也就是Stopped或Traced的缩写,表示进程处于暂停或者跟踪状态

X也就是Dead的缩写,表示进程已经消亡,所以不会在top或者ps命令中看到它


不可中断状态,这其实是为了保证进程数据与硬件状态一致,并且正常情况下,不可中断状态在很短时间内就会结束
所以,短时的不可中断状态进程,一般可以忽略
但如果系统或硬件发生了故障,进程可能会在不可中断状态保持很久,甚至导致系统中出现大量不可中断进程
这时就得注意下,系统是不是出现了I/O等性能问题


僵尸进程,这是多进程应用很容易碰到的问题
正常情况下,当一个进程创建了子进程后,它应该通过系统调用wait()或者waitpid()等待子进程结束,回收子进程的资源
而子进程在结束时,会向它的父进程发送SIGCHLD信号
所以,父进程还可以注册SIGCHLD信号的处理函数,异步回收资源

如果父进程没这么做,或是子进程执行太快,父进程还没来得及处理子进程状态,子进程就已经提前退出
那这时的子进程就会变成僵尸进程
换句话说,父亲应该一直对儿子负责,善始善终,如果不作为或者跟不上,都会导致“问题少年”的出现
通常,僵尸进程持续的时间都比较短,在父进程回收它的资源后就会消亡
或者在父进程退出后,由init进程回收后也会消亡
一旦父进程没有处理子进程的终止,还一直保持运行状态,
那么子进程就会一直处于僵尸状态。
大量的僵尸进程会用尽PID进程号,导致新进程不能创建,所以这种情况一定要避免




案例

实验环境
# 服务端(192.168.1.6)
配置:2CPU,4G内存,centos7.6_64     
预先安装docker、sysstat、perf、ab、dstat 等工具(yum install perf httpd-tools sysstat dstat -y)


dstat是一个新的性能工具,它吸收了vmstat、iostat、ifstat等几种工具的优点
可以同时观察系统的CPU、磁盘I/O、网络以及内存使用情况


1.在服务端第一个终端执行下面命令

# 注意跑太久可能会跑死服务器,及时停止
[root@local_sa_192-168-1-6 ~]# docker run --privileged --name=app -itd feisky/app:iowait


2.在服务端,第二个终端执行下面命令

# 如果一切正常,你应该可以看到如下所示的输出
[root@local_sa_192-168-1-6 ~]# ps aux | grep /app
root 4009 0.0 0.0 4376  1008  pts/0 Ss+ 05:51 0:00 /app
root 4287 0.6 0.4 37280 33660 pts/0 D+  05:54 0:00 /app
root 4288 0.6 0.4 37280 33668 pts/0 D+  05:54 0:00 /app

可以发现多个app进程已经启动,并且它们的状态分别是Ss+和D+
S表示可中断睡眠状态,D表示不可中断睡眠状态


s和+是什么意思呢?
s表示这个进程是一个会话的领导进程,而+表示前台进程组


进程组和会话,它们用来管理一组相互关联的进程
进程组表示一组相互关联的进程,比如每个子进程都是父进程所在组的成员
会话是指共享同一个控制终端的一个或多个进程组
比如,通过SSH登录服务器,就会打开一个控制终端(TTY),这个控制终端就对应一个会话
而在终端中运行的命令以及它们的子进程,就构成了一个个的进程组
其中,在后台运行的命令,构成后台进程组
在前台运行的命令,构成前台进程组

3.在服务端,第二个终端执行top命令,查看资源使用情况

# 按下数字1切换到所有CPU的使用情况,观察一会儿按Ctrl+C结束
[root@local_sa_192-168-1-6 ~]# top
top - 05:56:23 up 17 days, 16:45, 2 users, load average: 2.00, 1.68, 1.39
Tasks: 247 total, 1 running, 79 sleeping, 0 stopped, 115 zombie
%Cpu0 : 0.0 us, 0.7 sy, 0.0 ni, 38.9 id, 60.5 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu1 : 0.0 us, 0.7 sy, 0.0 ni, 4.7 id, 94.6 wa, 0.0 hi, 0.0 si, 0.0 st
...
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
4340 root 20 0 44676 4048 3432 R 0.3 0.0 0:00.05 top
4345 root 20 0 37280 33624 860 D 0.3 0.0 0:00.01 app
4344 root 20 0 37280 33624 860 D 0.3 0.4 0:00.01 app
1 root 20 0 160072 9416 6752 S 0.0 0.1 0:38.59 systemd
...


第一行的平均负载( Load Average),过去1分钟、5分钟和15分钟内的平均负载在依次减小,说明平均负载正在升高
而1分钟内的平均负载已经达到系统的CPU个数,说明系统很可能已经有了性能瓶颈

第二行的Tasks,有1个正在运行的进程,但僵尸进程比较多,而且还在不停增加,说明有子进程在退出时没被清理

CPU的使用率情况,用户CPU和系统CPU都不高,但iowait分别是60.5%和94.6%,好像有点儿不正常

每个进程的情况,CPU使用率最高的进程只有0.3%,看起来并不高
但有两个进程处于D状态,它们可能在等待I/O,但光凭这里并不能确定是它们导致了iowait升高


汇总一下
1.iowait太高了,导致系统的平均负载升高,甚至达到了系统CPU的个数
2.僵尸进程在不断增多,说明有程序没能正确清理子进程的资源


标签:状态,07,0.0,top,进程,root,CPU,僵尸
来源: https://www.cnblogs.com/lichengguo/p/15556790.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有