问题
系统中的定时任务,过一段时间之后,不能运行。通过系统命令查看到系统有大量sendmail进程,导致文件描述符耗尽。以下主要通过分析整个处理过程,供大家参考。
处理过程
根据以上问题,分析步骤如下:
1、首先手动执行了一下定时任务,结果执行失败,通过错误判断是文件描述符被用光了。具体报错如下:
"cannot open shared object file: Too many open files in system"
2、查看定时任务是否堆积,ps -ef | grep
没有发现任何任务在跑。猜测应该是其他问题导致,具体是什么,不清楚。
3、通过系统命令top看到有多个sendmail进程,然后ps -ef | grep sendmail
,发现大量进程。初步定位应该是sendmail的问题。首先将所有sendmail进程kill掉,然后定时任务可以执行了。一段时间后,重新查看进程,发现又有了一些sendmail进程,进一步定位问题。
/usr/sbin/sendmail -FCronDaemon -i -odi -oem -oi -t -f root
怀疑是crontab执行的时候起来的,先把进程kill了再说
[root@localhost ~]# ps -ef | grep '/usr/sbin/postdrop' | awk '{print $2}' | xargs kill -9
4、通过pstree发现,sendmail进程是有crond守护进程启动的。crontab怎么会启动sendmail进程?原来crond在执行脚本时会将脚本输出信息以邮件的形式发送给crond用户,但是sendmail进程堆积的原因是什么呢?
init───2*[bash]
├─crond──102*[crond─┬─sendmail]
│ └─sh───sh]
5、查看sendmail日志,发现大量的warning告警信息。经查原来是环境的postfix没有正常运行,导致大量sendmail进程阻塞。
postfix/postdrop[23110]: warning: mail_queue_enter: create file maildrop/749274.23110: No such file or directory
6、根据博文[1]中的方法,将crontab的第一行添加:MAILTO=""
,然后查看确实没有了sendmail进程。
本以为解决了问题,但是过了几天发现系统负载升高,同样的方式查看,发现有了大量的postdrop进程,pstree发现发生了变化,原来postdrop进程是sendmail进程产生的,也就是说sendmail并没有完全解决掉。
init───2*[bash]
|-crond---125*[crond---sendmail---postdrop]
│ │ └─sh───sh]
7、查看sendmail日志(/var/log/maillog),发现大量的warning告警信息,错误显示是权限问题,那么首先查看maildrop目录的权限(/var/spool/postfix/maildrop/),修改权限后,查看没有了该warning信息。
告警信息如下:
postfix/postdrop[21235]: warning: mail_queue_enter: create file maildrop/577217.21235: Permission denied
执行命令如下:
chown postfix.postdrop /var/spool/postfix/public -R
chown postfix.postdrop /var/spool/postfix/maildrop -R
chmod 777 /var/spool/postfix/maildrop -R (仅修改以上两步时,仍然有告警。)
8、基于稳妥考虑,在crontab -e中开始加上MAILTO="",在/etc/crontab中设置MAILTO="",这样保证crontab不发送日志,也就不会产生sendmail进程了,继续观察,本来以为问题解决了,其实并没有。。。,过来一阵子又出现sendmail的进程,进程查。查到/etc/cron.d/下面的文件(crontab会加载里面的文件)刚好里面有个0hourly
,怀疑是这个问题,打开这两个文件一看:
# Run the hourly jobs
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
01 * * * * root run-parts /etc/cron.hourly
crontab并没有加&>/dev/null
,就会触发sendmail,问题定位到了,将pcp开头的两个文件的crontab命令加上&>/dev/null
如下:
# Run the hourly jobs
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
01 * * * * root run-parts /etc/cron.hourly &>/dev/null
9、通过pstree检查进程树状态,crond守护进程不会调用sendmail了,具体如下所示:
init───2*[bash]
├─crond
除此之外,在查看sendmail日志的时候,发现以下告警信息较多,应该是系统设置上有些问题。经查是由于/etc/postfix/main.cf配置文件中,inet_protocols = all的原因。修改配置为inet_protocols = ipv4后,warning信息没有了。
postfix/postdrop[17405]: warning: inet_protocols: IPv6 support is disabled: Address family not supported by protocol
postfix/postdrop[17405]: warning: inet_protocols: configuring for IPv4 support only
参考
1、crond 引起大量sendmail进程:
http://www.cnblogs.com/skyaccross/archive/2013/03/21/crond_sendmail.html
2、crond-sendmail-postdrop导致Linux定期死掉的完整解决过程实录:
http://blog.csdn.net/smstong/article/details/8920808
3、postdrop: create file maildrop/xxx: Permission denied:
http://linuxhostingsupport.net/blog/postdrop-mail_queue_enter-create-file-maildrop-permission-denied
4、"IPv6 support is disabled" warnings:
http://unix.stackexchange.com/questions/64414/ipv6-support-is-disabled-warnings
本文转载自 王恒-Henry 的博客,原文连接:Crontab导致Linux文件描述符枯竭