PHP发送邮件时出现504 Gateway Time-Out问题求助
排查AWS生产环境Amazon SES发送邮件504 Gateway Time-Out的思路
看起来你在AWS生产环境用Amazon SES发邮件时碰到了棘手的504网关超时问题,测试环境同配置却正常,确实挺头疼的。结合你的描述,我整理几个排查方向,你可以逐一试试:
AWS网络层面的限制检查
AWS默认会对EC2实例的25端口出站流量做限制(防止垃圾邮件),如果测试环境已经申请解除了这个限制但生产环境没弄,大概率会出现连接超时。你可以:- 先尝试更换SES推荐的端口:把配置里的
$phpmailer->Port = 25;改成587(STARTTLS)或465(SSL),这两个端口默认没有出站限制,很多时候换端口就能解决问题。 - 检查生产EC2实例的安全组:确保出站规则允许目标端口(25/587/465)访问SES的SMTP端点地址。
- 查看VPC网络ACL:确认没有拒绝出站到SES SMTP端点的流量规则,ACL是无状态的,入站和出站都要配置允许。
- 如果实例在私有子网,检查NAT网关的配置:确保NAT网关能正常转发SMTP出站流量,路由表指向正确。
- 先尝试更换SES推荐的端口:把配置里的
SES账户与生产环境验证
虽然测试环境正常,但生产环境的SES可能有不同的状态:- 确认生产SES账户是否脱离沙箱模式:沙箱里只能发送到已验证的邮箱,若你发送到未验证邮箱可能触发延迟或失败,虽然不一定直接导致504,但值得排查。
- 检查SES发送配额和速率限制:去SES控制台的「Metrics」页面看看,有没有达到发送上限被限流,限流会导致请求排队超时。
- 确认生产环境的发件人域名/邮箱是否完成验证:如果验证过期或未完成,SES会拒绝请求,也可能表现为超时。
PHP与服务器的隐藏配置限制
你已经调整了php.ini的参数,但可能存在没生效或其他限制:- 确认php.ini配置是否生效:在代码里临时加
phpinfo();输出,查看max_execution_time和default_socket_timeout的实际值,避免改了错误的配置文件(比如FPM和CLI的php.ini是分开的),别忘了修改后重启PHP服务。 - 检查服务器防火墙:比如iptables、ufw,有没有出站规则限制25/587/465端口,生产环境可能开启了防火墙但测试环境没配置。
- 调整Web服务器的超时设置:如果用Apache,检查
Timeout指令;用Nginx的话看proxy_read_timeout,这些值如果比PHP的执行时间短,会提前触发504网关超时。
- 确认php.ini配置是否生效:在代码里临时加
SMTP连接调试
增加调试日志能帮你定位具体卡住的环节:- 把
$phpmailer->SMTPDebug = 1;改成2,这样会输出完整的SMTP交互日志,你能看到是连接阶段超时,还是TLS握手失败,或者发送邮件命令时卡住。 - 在生产服务器用命令行测试连接:
- 用telnet测试端口连通性:
telnet 你的SES SMTP Host 25,如果连不通,直接确认是网络问题。 - 用openssl测试TLS连接:
openssl s_client -connect 你的SES SMTP Host:25 -starttls smtp,看是否能正常完成TLS握手,有没有证书错误。
- 用telnet测试端口连通性:
- 把
其他AWS服务影响
- 检查是否启用了WAF:如果WAF有拦截SMTP出站请求的规则,或者速率限制太严格,会导致请求被阻断超时。
- 查看CloudWatch日志:EC2实例的系统日志、PHP错误日志、SES的投递日志里,可能藏着更详细的错误线索,帮你缩小排查范围。
内容的提问来源于stack exchange,提问作者docode
相关产品推荐
相关产品推荐

