3.24下午接到客户反馈,系统出现了大量的sendmail及postdrop进程,导致系统崩溃。需要协助排查。具体故障截图及处理过程如下。

客户提供的截图:

linux服务器管理与配置(linux服务器大量的sendmail及postdrop进程故障排查)(1)

linux服务器管理与配置(linux服务器大量的sendmail及postdrop进程故障排查)(2)

可以看到系统产生了大量的sendmail及postdrop进程,1分钟产生一个。

通过查看对应进程的父进程确定是crond导致的

linux服务器管理与配置(linux服务器大量的sendmail及postdrop进程故障排查)(3)

应急措施 停止crond

service stop crond

杀掉sendmail及postdrop进程

ps -ef|grep "/usr/sbin/sendmail"|grep -v grep |awk '{print $2}'|xargs kill ps -ef|grep "/usr/sbin/postdrop"|grep -v grep |awk '{print $2}'|xargs kill

同时客户反馈上午的时候发现/var目录满了 然后重启了主机 把postfix服务给停止了。通过网上查看crond 导致大量的sendmail进程有相关的案例.

联系客户查看crontab是否配置定时任务。结果如下

linux服务器管理与配置(linux服务器大量的sendmail及postdrop进程故障排查)(4)

系统中存在两个定时任务,一个是用于nginx日志切割的,一个是用于华三虚拟化agent检测的。注意上图的/etc/crontab里面的mail="root"。

按照网上的解决方案,我先把日志切割的任务添加一下日志输出重定向。

linux服务器管理与配置(linux服务器大量的sendmail及postdrop进程故障排查)(5)

然而添加的时候出现设备上面没有空间的报错。

查看文件系统使用率正常

linux服务器管理与配置(linux服务器大量的sendmail及postdrop进程故障排查)(6)

联想到大量的sendmail可能会产生很多小文件,查看i节点信息,果然i节点满了

linux服务器管理与配置(linux服务器大量的sendmail及postdrop进程故障排查)(7)

处理i节点问题

cd /var/spool/postfix/maildrop ls | xargs -n 1000 rm -rf //要批量删,一次1000个,直接rm可能删不成功

再次查看恢复正常

linux服务器管理与配置(linux服务器大量的sendmail及postdrop进程故障排查)(8)

再次修改contab脚本,正常修改。

linux服务器管理与配置(linux服务器大量的sendmail及postdrop进程故障排查)(9)

启动crond服务。经过十几分钟的观察sendmail服务未启动。

总结:

进程启动顺序:postdrop是由sendmail启动的,而sendmail又是由crond启动的。问题成因:crond在执行脚本时会将脚本输出信息以邮件的形式发送给系统用户,所以必然要调用sendmail,而sendmail又会调用postdrop发送邮件,但是如果系统的postfix服务没有正常运行,那么邮件就会发送不成功,造成sendmail、postdrop、crond进程就无法正常退出,形成大量的僵尸进程

所以根本的原因还是postfix服务被禁用了导致的。

解决这个问题有两个办法:

在crontab末尾加上 >/dev/null 2>&1. 或&> /dev/null 例如*/10 * * * * /home/a.sh >/dev/null 2>&1 另外一种方法是crontab第一行加入,那么后面执行的crontab脚本就不会发送mail了 MAILTO=""

man 5 contab查看crontab帮助

In addition to LOGNAME, HOME, and SHELL, cron(8) looks at the MAILTO variable if a mail needs to be send as a result of running any commands in that particular crontab. If MAILTO is defined (and non-empty), mail is sent to the specified address. If MAILTO is defined but empty (MAILTO=""), no mail is sent. Otherwise, mail is sent to the owner of the crontab. This option is useful if you decide to use /bin/mail instead of /usr/lib/sendmail as your mailer. Note that /bin/mail does not provide aliasing and UUCP usually does not read its mail. If MAILFROM is defined (and non-empty), it is used as the envelope sender address, otherwise, ``root'' is used。

,