简体   繁体   English

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

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

I am installing an email-sending capability on one PHP page on my server. 我正在我的服务器上的一个PHP页面上安装电子邮件发送功能。 I want to be able to specify the gmail account to send from so I am using PHPMailer. 我希望能够指定要发送的Gmail帐户,因此我使用的是PHPMailer。 However, every time I load the page that sends the email, I get a 504 Gateway timeout error after about 30 seconds. 但是,每次加载发送电子邮件的页面时,我都会在大约30秒后收到504网关超时错误。 Eventually, the email is sent (I receive it about 5 minutes later) but is this normal? 最终,电子邮件被发送(我在大约5分钟后收到),但这是正常的吗? It is a very basic text email. 这是一个非常基本的文本电子邮件。

This is my code to send the email 这是我发送电子邮件的代码

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 timeouts are pretty long (at least 5 mins). SMTP超时很长(至少5分钟)。 The 504 you're getting is because the timeout between nginx and your PHP cgi (I'd assume you're running FPM) is shorter, so by the time PHP generates an error, nginx has already dropped the connection, so you're getting no feedback. 你得到的504是因为nginx和你的PHP cgi之间的超时(我假设你正在运行FPM)更短,所以当PHP生成错误时,nginx已经放弃了连接,所以你是得不到反馈。

It's fairly likely this is a DNS or firewall issue on your host - check out the troubleshooting docs . 这很可能是您主机上的DNS或防火墙问题 - 请查看故障排除文档

Digital Ocean states in their support center how to enable services like smtp to prioritize connections over IPv4 whilst still maintaining accessible IPv6 functionality to your droplet otherwise. 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. 您可以优先使用IPv6上的IPv4地址,以便您可以继续发送电子邮件而不禁用IPv6。 You would do that by editing the Droplet's /etc/gai.conf file and removing the comment (#) from the following line: 您可以通过编辑Droplet的/etc/gai.conf文件并从以下行删除注释(#)来实现:

Default Configuration: #precedence ::ffff:0:0/96 100 默认配置:#precedence :: ffff:0:0/96 100

Configuration with Priority to IPv4: precedence ::ffff:0:0/96 100 IPv4优先级配置:precedence :: ffff:0:0/96 100

This has been checked and confirmed working by me for the PHPMailer-issue where request would time out (504 Gateway Time-out) but where the mail is still eventually delivered (Ubuntu 16.04 LEMP). 这已被我检查并确认为PHPMailer问题工作,其中请求将超时(504网关超时)但邮件仍最终交付(Ubuntu 16.04 LEMP)。

This is because Ngninx drops the connection to PHP-FPM whilst the php-script is still running in the background trying to resolve an IPv6 SMTP-address, before finally moving over to IPv4 on no-success. 这是因为Ngninx放弃了与PHP-FPM的连接,而php-script仍然在后台运行,尝试解析IPv6 SMTP地址,最后在没有成功的情况下转移到IPv4。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM