PHPMailer 在我使用 nginx 的 Digital Ocean 服务器上导致 504 超时错误

PHPMailer is causing 504 timeout error on my Digital Ocean server using nginx

我正在服务器上的一个 PHP 页面上安装电子邮件发送功能。我希望能够指定要发送的 gmail 帐户,所以我使用的是 PHPMailer。但是,每次我加载发送电子邮件的页面时,我都会在大约 30 秒后收到 504 网关超时错误。最终,电子邮件已发送(大约 5 分钟后我收到了),但这正常吗?这是一封非常基本的文本电子邮件。

这是我发送电子邮件的代码

require '../html/lib/phpmailer/PHPMailerAutoload.php';


//Create a new PHPMailer instance
$mail = new PHPMailer;

//Tell PHPMailer to use SMTP
$mail->isSMTP();

//Enable SMTP debugging
// 0 = off (for production use)
// 1 = client messages
// 2 = client and server messages
$mail->SMTPDebug = 2;

//Ask for HTML-friendly debug output
$mail->Debugoutput = 'html';

//Set the hostname of the mail server
$mail->Host = 'smtp.gmail.com';

//Set the SMTP port number - 587 for authenticated TLS, a.k.a. RFC4409 SMTP submission
$mail->Port = 587;

//Set the encryption system to use - ssl (deprecated) or tls
$mail->SMTPSecure = 'tls';

//Whether to use SMTP authentication
$mail->SMTPAuth = true;

//Username to use for SMTP authentication - use full email address for gmail
$mail->Username = "user@gmail.com";

//Password to use for SMTP authentication
$mail->Password = "pw";

//Set who the message is to be sent from
$mail->setFrom('from@gmail.com', 'First Last');

//Set an alternative reply-to address
//$mail->addReplyTo('@example.com', 'First Last');

//Set who the message is to be sent to
$mail->addAddress('recip@gmail.com', 'recip');
$mail->Subject = 'PHPMailer GMail SMTP test 2';

//Read an HTML message body from an external file, convert referenced images to embedded,
//convert HTML into a basic plain-text alternative body
//$mail->msgHTML(file_get_contents('contents.html'), dirname(__FILE__));

//Replace the plain text body with one created manually
$mail->Body = 'This is another plain-text message body';

//Attach an image file
//$mail->addAttachment('images/phpmailer_mini.png');

//send the message, check for errors
if (!$mail->send()) {
    echo "Mailer Error: " . $mail->ErrorInfo;
} else {
    echo "Message sent!";
}

SMTP 超时时间很长(至少 5 分钟)。你得到的 504 是因为 nginx 和你的 PHP cgi(我假设你是 运行 FPM)之间的超时时间更短,所以到 PHP 时会产生错误,nginx 已经断开连接,因此您没有收到任何反馈。

这很可能是您主机上的 DNS 或防火墙问题 - 查看 the troubleshooting docs

Digital Ocean 在其支持中心说明了如何启用 smtp 等服务来优先考虑 IPv4 连接,同时仍然保持 Droplet 可访问的 IPv6 功能。

You can give priority to IPv4 addresses over IPv6 so that you can continue to send out email without disabling IPv6. You would do that by editing the Droplet's /etc/gai.conf file and removing the comment (#) from the following line:

Default Configuration: #precedence ::ffff:0:0/96 100

Configuration with Priority to IPv4: precedence ::ffff:0:0/96 100

这已被我检查并确认可以解决 PHP 请求超时(504 网关超时)但邮件最终仍会送达的 Ubuntu 邮件问题16.04 LEMP).

这是因为 Ngninx 断开了与 PHP-FPM 的连接,而 php-脚本仍在后台 运行 尝试解析 IPv6 SMTP 地址,最终失败时转移到 IPv4。