Django邮件功能本地运行正常但生产环境无响应该如何排查?
出站端口封禁
大部分云服务商、服务器运营商会默认封禁25、587等邮件服务相关的出站端口,避免垃圾邮件发送。本地Windows网络无此限制所以运行正常,服务器无法建立连接时就会出现长时间无响应的挂起状态。
可以先在服务器上执行命令测试端口连通性:telnet mail.host.com 587
如果连接失败,需要去服务器安全组、ufw防火墙放行587出站规则,部分运营商封禁需要单独申请解封。
同时建议在settings.py中添加超时配置,避免无限制挂起:EMAIL_TIMEOUT = 10环境变量加载异常
Linux系统环境变量大小写敏感,你使用os.getenv('EMAIL_HOST_PASSWORD')获取密码,需要确认服务器运行Django进程的环境中是否正确配置了对应名称的环境变量:
如果用systemd托管服务,需要在service配置文件的[Service]段添加Environment="EMAIL_HOST_PASSWORD=你的密码";如果用虚拟环境运行,需要确认activate脚本中是否写入了对应环境变量。
环境变量缺失会导致认证环节异常,也可能引发连接挂起。TLS配置缺失
587端口默认需要开启STARTTLS加密,你当前的配置中没有开启TLS相关配置,不同系统的默认加密策略差异可能导致连接失败。可以在settings.py中补充配置:EMAIL_USE_TLS = True
部分自建邮件服务器如果使用自签证书,还需要补充证书路径配置,或者临时添加EMAIL_SSL_CERTFILE = None跳过证书验证排查问题。附件访问权限异常
Linux文件系统有严格的权限控制,你代码中用到的model.document.path对应的文件,需要确认Django运行用户是否有读取权限,同时注意路径大小写是否和实际存储路径一致(Linux大小写敏感,Windows不敏感)。可以先注释掉mail.attach_file(model.document.path)这行代码,测试不带附件能否正常发送,排除附件相关问题。DNS解析异常
确认服务器是否能正常解析mail.host.com域名,可以在服务器上执行nslookup mail.host.com测试,如果解析失败,需要修改服务器的DNS配置为公共DNS(比如114.114.114.114、8.8.8.8)后重试。
内容的提问来源于stack exchange,提问作者Sajjad Ahmed Shaaz

