发送电子邮件时使用Gmail SMTP的PHPMailer会变慢

RMK*_*RMK 6 php windows phpmailer

我发现很少有较旧的线程有类似的问题,但大多数没有答案,或者如果有的话,这些建议与我的情况无关.

我在一个点上完成了PHP邮件功能的设置,效果很好.我不得不在一点上格式化硬盘并从头开始设置服务器.之后,PHP邮件功能变得缓慢.在研究解决方案时,我发现大多数人都推荐使用PHPMailer.我改用了,但问题仍然存在.

大多数情况下,我每页至少发送两封电子邮件,但是使用相同的对象.大约有3-4秒的延迟.请在下面找到相关代码($ email1和$ email2是包含有效电子邮件地址的数组):

function sendEmail ($email1, $subject1, $message1, $email2, $subject2, $message2) 
{
    require_once('../PHPMailer/class.phpmailer.php');

    $mail = new PHPMailer();
    $mail->IsSMTP(); 
    $mail->SMTPDebug = 0; 
    $mail->SMTPAuth = true; 
    $mail->SMTPSecure = 'ssl';
    $mail->Host = "smtp.gmail.com";
    $mail->Port = 465; 
    $mail->IsHTML(true);
    $mail->Username = $gmail_username;
    $mail->Password = $gmail_password;
    $mail->SetFrom($gmail_address,$email_title);

    $mail->Subject = $subject1;
    $mail->Body = $message1;
    foreach($email1 as $k => $v) {  $mail->AddAddress($v);  }       
    if(!$mail->Send()) {    $emailreturn['cust'] = 0;   } else {    $emailreturn['cust'] = 1;   }
    $mail->ClearAddresses();

    $mail->Subject = $subject2;
    $mail->Body = $message2;
    foreach($email2 as $k => $v) {  $mail->AddAddress($v);  }
    if(!$mail->Send()) {    $emailreturn['partner'] = 0;    } else {    $emailreturn['partner'] = 1;    }
    $mail->ClearAddresses();
}
Run Code Online (Sandbox Code Playgroud)

我没有通过调试和消息看到任何错误,发送电子邮件只需要比平时更长的时间.

我尝试过的:

  • 我关闭防火墙只是为了测试它,它是一样的.
  • 切换到'tls',这使它更慢
  • 使用对象发送每封电子邮件,每封电子邮件延迟3-4秒
  • 使用可选配置,注释掉或设置为false,都具有相同的结果

邮件程序设置中是否还有其他内容,或者我应该检查一些幕后配置?谢谢

Gre*_*ett 20

缓慢(或由于超时导致的失败)是因为Google支持IPv6寻址,但您的网络却不支持.(例如Digital Ocean尚不支持IPv6用于SMTP流量).所以,使用这个:

$mail->Host = gethostbyname("smtp.gmail.com");
Run Code Online (Sandbox Code Playgroud)

gethostbyname()将返回IPv4地址.

对我来说,我的PHPMailer脚本从大约2分钟的执行时间变为<4秒

  • 这个答案是正确的,但是通过TLS(也许是SSL)登录失败,因为主机现在只是一个IP地址.您还必须更改SMTPOptions:`$ mail-> SMTPOptions = array('ssl'=> array('verify_peer_name'=> false));`. (7认同)

小智 6

如果发送电子邮件之间的延迟确实是一个关键问题,您是否考虑过实施多线程?每条消息的延迟可能是相同的,但如果你一次发送两个enails,它基本上会减少一半.

一种简单的方法是实现队列,并通过非阻塞HTTP/SQL调用发送消息.通过这种方式,您可以以最小的延迟发送任意数量的内容.

我还建议,如果可能的话,找到延迟最低的gmail服务器并将其添加到您的hosts文件中以消除DNS查找.

还有一些性能提示:你只需要require_once()作为包含文件,但是你需要在每次调用时都需要它(顺便说一句,include_once()更快).为什么不只创建一个$ mail对象并在需要调用sendemail()时重用它?

另外为什么不将message1,subject1等作为一个数组传递,将message2,subject2等作为第二个数组传递?通常在过程调用期间传递几个参数(至少在经典编程中)往往会加快速度.

暂时不说 - 不知道这是否可行 - 也许有一种方法可以保持与smtp.gmail.com的持续连接.这也将消除大量开销.

此外,通过您自己的meial服务器中继您的消息选项?它会消除延迟.

最后,我遇到了Google的回复:[ Gmail发送限制 `

Thank you for your message.

    I understand you have a query regarding the Google Apps for Business sending limits. As 
mentioned     in our Help Center article at http://support.google.com/a/bin/answer.py?hl=en&
answer=166852,     the daily limitation is 2000 messages in a 24-hour period not day. In general, our 
servers can tolerate one message per second until sending limits are hit. We really don't 
have an hourly or minute limitation for sending. If you send messages too quickly you may     
get rate-limited but the account should not lock out.

By rate-limt, since in general one message per second, if you try to send too many messages per second 
you may get a message telling you that the message cannot be send or you must wait before sending a 
message.

`
Run Code Online (Sandbox Code Playgroud)

如果你需要,我会很乐意写一个符合这些限制的课程.请让我知道,不应该花太长时间.

建议:使用其他电子邮件主机/中继


shu*_*van 0

消除从客户端到服务器的等待的解决方案之一是将发送电子邮件移至 crontab。因此,当客户端单击发送时,php 将电子邮件和消息添加到队列中,然后每分钟通过 cron 发送排队的消息。

此外,您可以通过$start = microtime(true);在脚本顶部添加调试信息并echo "Line ".__LINE__.":"round(microtime(true) - $start, 3)."sec<br>";在每一行进行回显来将调试信息添加到脚本中。