Linux僵尸进程
前言
僵尸进程产生代表了系统中有错误产生同时过多的僵尸进程也会影响系统的稳定运行。
一、僵尸进程是什么?
在Linux系统中,一个进程结束了,但是其父进程没有等待(调用wait/waitpid)它,那么它将变成一个僵尸进程。通过PS命令可以查看其带有defunct的标志,僵尸进程是一个早已死亡的进程,但在进程表中仍占据一个位置;但是如果该进程的父进程已经先结束了,那么该进程就不会变成僵尸进程。
二、僵尸进程产生原因?
一个进程在调用exit命令结束自己的生命时候,其实它没有真正的被销毁,而是留下一个称为僵尸进程的数据结构(系统调用exit,它的作用是使进程退出,但也仅仅限于将一个正常的进程变成一个僵尸进程,并不能将其完全销毁)。在Linux进程的状态中,僵尸进程是非常特殊的一种,它已经放弃了几乎所有的内存空间,没有任何可执行代码,也不能被调度,仅仅在进程列表中保留一个位置,记录在进程的退出状态等信息供其他进程收集,除此之外,僵尸进程不在占有任何内存空间。
每个进程结束的时候,系统都会扫描当前系统中所运行的所有进程,看看有没有哪个进程是刚刚结束的这个进程的子进程,如果是的话,就由init进程来接管他,成为他的父进程,从而保证每个进程都会有一个父进程。而init进程会自动wait其子进程,因此被Init接管的所有进程都不会变成僵尸进程,所以正常情况下Linux系统不会产生僵尸进程。
僵尸进程需要父进程来为它收尸…如果父进程结束了,那么init进程会自动接手这个子进程,为它收尸,它还是能被清除的,但是如果父进程是一个循环,不会结束,那么子进程就会一直保持僵尸状态,这就是系统出现僵尸进程后即使处理了也会持续出现僵尸进程,因为僵尸进程代表了有应用或者脚本等运行出现异常;
二、如何排查僵尸进程
1.查询僵尸进程
1. top>> task (line)>> zombie.. 查看僵尸进程个数
2. ps -ef |grep -v grep |grep defunct 查看僵尸进程具体信息
2.确认僵尸进程产生原因
例子:linux系统的sendmail产生的僵尸进程
sendmail进程是由系统计划任务(crond)引起,原因是当系统在执行计划任务的时候,如果有标准输出或者标准错误输出(通常是脚本运行报错同时输出不规范并且未重定向)会触发sendmail程序,来发送邮件,如果输出信息太大的话会引发失败,成为僵尸进程。
三、处理僵尸进程
直接Kill 僵尸子进程;如果kill 子进程的无效,可以尝试kill 其父进程来解决问题,把父进程杀掉,父进程死后,僵尸进程称为“孤儿进程”,过继给1号进程init,init始终负责清理僵尸进程,它产生的所有僵尸进程跟着消失;
然后根据僵尸进程产生原因解决根本问题。
例子:linux系统的sendmail产生的僵尸进程
计划任务配置输出重定向,对于不需要计划任务日志的可以输出重定向到空设备中(/dev/null),即可解决不再产生sendmail异常进程的问题 。具体的配置方法示例:
# crontab -e
利用 2>&1 输出入重定向
* * * * * /bin/sh /tmp/test.sh > dev/null 2>&1
或利用 &> 输出入重定向
* * * * * /bin/sh /tmp/test.sh &> dev/null
或在计划任务的首航添加 MIALTO=""
MIALTO="" * * * * * /bin/sh /tmp/test.sh
总结
1、首先,可以使用top命令来查看服务器当前是否有僵尸进程,下图中可以看到僵尸进程的提示,如果数字大于0,那么意味着服务器当前存在僵尸进程:
2、通过ps -ef |grep -v grep |grep defunct 查看僵尸进程具体信息,这里根据僵尸进程父PID可以看出这个是由定时任务引起的僵尸进程。同时根据同一个父PID可以看出是定时任务触发了脚本运行,由于定时任务不会产生僵尸进程可以排查是否是脚本运行产生的僵尸进程。
3、直接Kill -9 就可以处理僵尸进程
4、上例反欺诈的僵尸进程最后排查发现僵尸进程sendmail进程是由系统计划任务(crond)引起,原因是当系统在执行计划任务的时候,如果有标准输出或者标准错误输出(通常是脚本运行报错同时输出不规范并且未重定向)会触发sendmail程序,来发送邮件,如果输出信息太大的话会引发失败,成为僵尸进程。将输出重定向后就不再产生僵尸进程了。