通过批量邮件脚本发送数千封电子邮件时达到Sendmail异常。 sendmail是否为给定进程发送了电子邮件限制?

时间:2013-03-05 12:19:06

标签: zend-framework exception sendmail transactional-email bulk-mail

我对网络服务器中的问题有点绝望。我们的网络是一个拥有大量用户和活动的社区。我们向用户发送他们感兴趣的活动的个性化邮件。我们在脚本中遇到了处理这些邮件的问题。

我们的群发电子邮件脚本在发送数千封电子邮件时失败。它通常可以正常工作,但是当它必须发送比平时更多的电子邮件(aprox。25.000封电子邮件)时,它会反复抛出异常:

Unable to send mail. mail():
Could not execute mail delivery program '/usr/sbin/sendmail -t -i '

奇怪的是 sendmail在其他进程中正常工作这样的Web服务器,并且在PHP(Zend)中以相同的方式调用sendmail。当已发送大量电子邮件且没有错误时,Sendmail仅在PHP批量邮件脚本中失败。 当抛出第一个异常时,下一次调用sendmail也会失败。似乎已达到一些队列限制,但仅限于此过程!


PHP脚本代码

PHP批量邮件scipt主循环执行数千次。在每个循环中,传递调用sendMail使用不同的$email$user

// Sometimes, hundred thousands iterations
foreach($notifications as $j => $notification){
    ...
    $mail->setNotification($notification);
    $this->sendMail($mail, $user);
    ...          
}

$this->sendmail($mail, $user)调用Zend内部发送邮件的方法。它调用PHP本机方法mail

/**
 * Send mail using PHP native mail()
 *
 * @access public
 * @return void
 * @throws Zend_Mail_Transport_Exception if parameters is set
 *         but not a string
 * @throws Zend_Mail_Transport_Exception on mail() failure
 */
public function _sendMail()
{
    ...

        set_error_handler(array($this, '_handleMailErrors'));

        // CALL TO MAIL PHP NATIVE METHOD
        $result = mail(
            $this->recipients,
            $this->_mail->getSubject(),
            $this->body,
            $this->header,
            $this->parameters);
        restore_error_handler();
    }

    if ($this->_errstr !== null || !$result) {
        /**
         * @see Zend_Mail_Transport_Exception
         */
        require_once 'Zend/Mail/Transport/Exception.php';

        // HERE THE EXCEPTION IS THROWN
        throw new Zend_Mail_Transport_Exception('Unable to send mail. ' . $this->_errstr);
    }
}

进行sendmail运行

当批量邮件scipt工作正常时,请参阅ps -aux | grep sendmail输出

$ ps -aux | grep sendmail
root      6756  0.0  0.0  62240  2468 ?        Ss   18:19   0:08 sendmail: MTA: accepting connections          
root     25766  0.0  0.0  62668  3536 ?        Ss   22:43   0:00 sendmail: MTA: ./r17Lh1fX025764 eml4.in.gr.: client DATA status
root     30978  0.0  0.0  62460  2876 ?        Ss   22:46   0:00 sendmail: MTA: ./r17Lk8li030976 s1.m1r3.onet.pl.: user open
root     31462  0.0  0.0  62672  3536 ?        Ss   22:46   0:00 sendmail: MTA: ./r17LkSIg031460 mx2.hotmail.com.: client DATA status
root     31474  0.0  0.0  62672  3540 ?        Ss   22:46   0:00 sendmail: MTA: ./r17LkT54031472 mx2.hotmail.com.: client DATA status
root     31494  0.0  0.0  62668  4404 ?        Ss   22:46   0:00 sendmail: MTA: ./r17LkUXC031492 gmail-smtp-in.l.google.com.: client RCPT
root     31498  0.0  0.0  62668  3536 ?        Ss   22:46   0:00 sendmail: MTA: ./r17LkUn1031496 mx4.hotmail.com.: client DATA status
root     31502  0.0  0.0  62672  3536 ?        Ss   22:46   0:00 sendmail: MTA: ./r17LkUti031500 mx3.hotmail.com.: client DATA status
root     31506  0.0  0.0  62672  3500 ?        Ss   22:46   0:00 sendmail: MTA: ./r17LkUHw031504 mx4.hotmail.com.: client RCPT
root     31510  0.0  0.0  62672  3496 ?        Ss   22:46   0:00 sendmail: MTA: ./r17LkUth031508 mx3.hotmail.com.: client MAIL
root     31514  0.0  0.0  62668  4436 ?        Ss   22:46   0:00 sendmail: MTA: ./r17LkVPb031512 gmail-smtp-in.l.google.com.: client DATA status
root     31518  0.0  0.0  62460  2888 ?        Ss   22:46   0:00 sendmail: MTA: ./r17LkV9o031516 mx1.hotmail.com.: client EHLO
root     31522  0.0  0.0  62668  4404 ?        Ss   22:46   0:00 sendmail: MTA: ./r17LkVD4031520 gmail-smtp-in.l.google.com.: client RCPT
root     31526  0.0  0.0  62460  2852 ?        Ss   22:46   0:00 sendmail: MTA: ./r17LkVcF031524 mx3.hotmail.com.: user open

当脚本开始抛出异常时,ps -aux | grep sendmail输出几乎为空,如预期的那样

$ ps -aux | grep sendmail
root      6756  0.0  0.0  62240  2468 ?        Ss   Feb07   0:49 sendmail: MTA: accepting connections     

一些问题

我是sendmail的新手,所以我感谢任何帮助。如果您需要更多信息,请告诉我。

  • 简而言之,sendmail如何发送邮件?
  • sendmail是否有邮件限制(我们的服务器是专用的,没有托管服务提供商设置的特定限制)?
  • sendmail是否有任何进程队列限制了给定进程可以发送的邮件数量?
  • 百万美元的问题:为什么抛出异常以及如何解决它? : - )

提前感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

您为每封发送的电子邮件创建一个sendmail流程。 25_000封电子邮件可能会为您的计算机创建太多进程。

P.S。 您可以尝试通过新闻询问您的问题:comp.mail.sendmail - 添加一些内容以表明它不是“陷入困境的垃圾邮件”问题。

答案 1 :(得分:1)

sendmail如何发送邮件?

这不是一个短篇小说。 无论如何,为了减少sendmail进程的数量,您可以将php配置为通过smtp协议发送到127.0.0.1上的端口25(环回接口)。 它将创建 only “由root”sendmail进程拥有。

你还应该定义confDELAY_LA,confQUEUE_LA(延迟

当系统负载平均值高于配置的限制时,confDELAY_LA会降低接收新邮件的速度。它可能/将使您的脚本运行更长时间。

confQUEUE_LA跳过“立即”传递尝试 - 您最有可能增加队列运行程序进程数。

简而言之:您推送sendmail服务器超出限制标准简单配置被认为可以轻松处理。