我有点绝望与我们的networking服务器的问题。 我们的网站是一个有很多用户和活动的社区。 我们向用户发送他们感兴趣的活动的个性化邮件。 我们在处理这些邮件的脚本中遇到问题。
我们的批量电子邮件脚本在发送数千封电子邮件时失败 。 它通常工作正常,但当它发送比平常更多的电子邮件(aprox。25.000电子邮件)时,它会反复抛出exception:
Unable to send mail. mail(): Could not execute mail delivery program '/usr/sbin/sendmail -t -i '
奇怪的是, sendmail在其他进程(如Web服务器)中正常工作 ,sendmail在PHP(Zend)中的调用方式相同。 Sendmail只在PHP批量邮件脚本中失败,因为大量电子邮件已经无错地发送了。 当第一个exception抛出时,下一个sendmail调用也会失败 。 似乎已经达到了一些队列限制,但仅限于此过程!
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本地方法邮件 。
/** * 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 看ps -aux | grep 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
当脚本开始抛出exception时, ps -aux | grep sendmail 正如所料, 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的新手,所以我很感激任何帮助。 如果您需要更多信息,请告诉我。
在此先感谢您的帮助!
当您在基于Unix的系统上使用PHP调用mail()时,它会分叉sendmail命令,并将每个收件人作为parameter passing给命令行。 但是,在命令行中实际传递的参数的长度是有限制的 ! 这是一个非常大的限制,在Linux系统上默认为128KiB,但是25,000个电子邮件地址远远超过它。
要解决此问题,请以较小的批次发送邮件,例如每次收到1,000个收件人。 你应该发现把你的收件人数组分成1,000个组并循环遍历它们是微不足道的,但是如果没有,请访问我们的姐妹站点Stack Overflow以获得编程帮助。
但是,您的错误消息似乎表明您没有将任何收件人传递给该邮件。 所以你也许应该寻找一个编程错误,其中你没有recipients或recipients无效的情况下调用mail() 。
当你运行这个脚本时,你是以不同的用户身份运行它,而不是运行web服务器邮件脚本的用户? 对于运行脚本的用户来说,这可能是ulimit这样简单的事情。
任何邮件系统都会在短时间内淹没我的邮件。 也许你应该在发送一批消息(比如每100个左右)之后停一会儿。
无论如何,你应该仔细检查你在做什么。 我非常怀疑你有几千条重要的消息同时发送出去。 这样的行为只会让你进入人类已知的所有电子邮件黑名单中最深的地方。