2011-04-06 113 views
3

我有一个批处理电子邮件进程发送大约30,000封电子邮件。我遇到了一个奇怪的问题,它达到了大约85%的过程完成,然后电子邮件开始失败,并显示消息Could not execute: /usr/sbin/sendmail我正在使用名为PHPMailer 1.73的库和错误消息来自的相关代码是PHP的popen命令失败的原因

if([email protected]$mail = popen($sendmail, "w")) 
{ 
    $this->SetError($this->Lang("execute") . $this->Sendmail); 
    return false; 
} 

$sendmail值的形式为:/usr/sbin/sendmail -oi -f [email protected] -t

set_time_limit(0);,使该脚本将不会超时。

有无论如何找出为什么突然popen()开始失败?操作系统是否会耗尽文件描述符或达到其他限制?

我应该如何解决这个问题?我应该睡觉,然后在失败之前多次重试popen()几次?

更新:感谢马尔科的建议,看看proc_open()我在proc_open documentation发现了一个评论,如果它返回FALSE这可能意味着你跑了文件描述符,或者你是内存不足。我发现我的过程正在使用20G的记忆。但是如果memory_limit设置为64M,怎么会占用那么多内存呢?那么,运行exec()popen()proc_open()的外部程序似乎不会违反PHP的内存限制。看到这个问题的更多信息,Debugging memory usage in mod_php。我仍然不确定这是如何发生的,但我怀疑存在某种内存泄漏。

总之,如果您的文件描述符不足或内存不足,则popen()proc_open()可返回FALSE

+0

您的服务器是否配置了每小时/天的最大数量的smtp中继?什么是您的脚本执行超时设置为? – 65Fbef05 2011-04-06 19:42:35

+0

也可能会用尽PID。较老的Unix系统(特别是linux)有2^16个pid的上限。听起来30,000封电子邮件似乎越来越接近,包括常规系统流程。尽管如此,我不愿意看到系统负载会带来30,000多个sendmail实例徘徊不前。 – 2011-04-06 20:23:48

回答

1

我建议使用proc_open代替。使用起来稍微复杂一些,但可以访问stdout和stderr。这两个管道上的消息将为您节省大量的调试时间。

如何使用,请阅读PHP文档中的示例和注释。