首页 > 编程问答 >在生产中使用 Djoser 和 Django 发送电子邮件时出现“504 网关超时”

在生产中使用 Djoser 和 Django 发送电子邮件时出现“504 网关超时”

时间:2024-08-01 08:52:57浏览次数:13  
标签:python django nginx djoser

当我使用 Djoser 进行用户注册和登录管理时,我在 Django 生产环境中遇到问题。当用户请求创建帐户时,API 需要大约一分钟的时间,然后返回 504 Gateway Time-out 错误。在我的本地环境中,该过程正常工作,并且发送激活电子邮件没有任何问题。

我尝试过的:

  1. 增加了 Nginx 中的超时选项

    server {
        listen ${LISTEN_PORT};
    
        location /static {
            alias /vol/web/static;
        }
    
    
        location / {
            uwsgi_pass              ${APP_HOST}:${APP_PORT};
            include                 /etc/nginx/uwsgi_params;
            client_max_body_size    10M;
    
            # new code
            uwsgi_read_timeout       300s; 
            proxy_read_timeout       300s;
            proxy_connect_timeout    300s;
            proxy_send_timeout       300s;
        }
    }
    

这改变了错误。现在超过 2 分钟后我收到错误 Server Error (500) 但我仍然没有收到电子邮件。需要注意的是,我在本地几乎立即收到了电子邮件。

  1. 在电子邮件发送函数中添加了日志。

    class ActivationEmail(email.ActivationEmail):
        template_name = "user/email/activation.html"
    
        def send(self, to, *args, **kwargs):
            print(f"Sending activation mail to {to}")
            try:
                super().send(to, *args, **kwargs)
            except:
                print(f"Couldn't send mail to {to}")
                raise
            print(f"Activation mail sent successfully to {to}")
    

该函数似乎被正确调用,但 super().send(to, *args, **kwargs) 永远不会返回。

我还检查了环境变量以确保它们在本地和生产环境之间保持一致。本地和生产中的电子邮件配置相同。但是,在生产中,电子邮件不会到达收件箱,并且 504 或 500 错误仍然存​​在。

我认为错误来自 nginx,因为本地我没有 nginx 配置。这是两种环境之间的主要区别。但到目前为止,我在 nginx 中的超时选项中所做的更改只是更改了错误,而没有解决问题。

问题:

在生产中发送电子邮件时可能导致 504 错误和 500 错误的原因是什么?我应该在 Nginx 或电子邮件设置中检查任何其他配置吗?我该如何诊断和解决这个问题?


“504 网关超时”错误以及电子邮件发送函数挂起且永不返回的事实强烈表明问题出在你的 Django 应用程序试图连接到的 外部邮件服务器 上。Nginx 只是充当反向代理,在达到超时限制后报告问题。

以下是你可以采取的一些故障排除步骤:

1. 检查邮件服务器的连接性:

  • 从你的服务器/生产环境中,尝试 ping 你的邮件服务器。 这将验证是否存在网络连接问题。 bash ping your_mail_server_hostname
  • 尝试使用 telnet 连接到你的邮件服务器的 SMTP 端口(通常为 25 或 587)。 这将帮助你了解端口是否可访问且服务器是否响应。 bash telnet your_mail_server_hostname 25

2. 检查邮件服务器的日志:

  • 你的邮件服务器的日志应包含有关连接尝试以及可能发生的任何错误的信息。查看这些日志以获取有关 Django 应用程序为何无法发送电子邮件的线索。
  • 具体查找在用户尝试在你的应用程序中注册时发生的任何错误消息或拒绝连接。

3. 验证你的电子邮件设置:

  • 双重、三重检查你的生产 Django 设置中的电子邮件配置是否正确。
    • 主机名和端口: 确保这些是正确的,并且你的应用程序可以从其运行的环境中访问它们。
    • 凭据: 如果你的邮件服务器需要身份验证,请验证你使用的是正确的用户名和密码。
    • TLS/SSL: 确认你是否正确配置了 TLS/SSL 设置以匹配你的邮件服务器的要求。

4. 测试不同的电子邮件后端(可选,但有助于排除故障):

  • 为了隔离问题是否与你的电子邮件设置或邮件服务器有关,请尝试暂时切换到像 console 后端这样的不同后端,该后端将在你的终端中打印电子邮件,或者像 Mailgun 或 SendGrid 这样的基于事务性电子邮件的服务。
    • 如果切换后端解决了该问题,那么问题几乎肯定出在你的原始邮件服务器配置上。

5. 分析代码以进行长时间运行的任务:

  • 虽然不太可能,但如果你确定邮件服务器连接正常,请仔细检查你的 ActivationEmail 类或 send 方法中的代码以查找任何可能导致延迟的意外长时间运行的任务或逻辑。
    • 例如,是否进行了任何不必要的数据库查询或 API 调用?

额外的提示:

  • 详细日志记录: 在你的电子邮件发送代码周围添加更多详细的日志记录(尝试/捕获块),包括发送的电子邮件参数和收到的任何异常或错误消息。
  • 逐步调试: 如果可能,请尝试使用调试器逐步执行代码,以查看在尝试发送电子邮件时究竟发生了什么。

通过系统地完成这些步骤,你应该能够找出问题的原因并实施解决方案以确保你的 Django 应用程序能够在生产环境中可靠地发送电子邮件。

标签:python,django,nginx,djoser
From: 78818581

相关文章

  • 在 Python Langchain 应用程序的 Docker 文件中运行 Ollama
    背景信息我有一个使用langchain和Ollama的Python应用程序。在本地运行这个程序效果非常好,因为我的机器上运行着Ollama客户端。我想要做的是在无服务器平台(例如GCR)上托管这个应用程序,为了做到这一点,我需要容器化应用程序。这对于应用程序的python端来说很容......
  • 跟踪 VScode 中的 python 警告
    我想知道哪一行代码导致我的代码中引发警告。可以在VScode中实现吗?例如,我在终端中看到警告:目前,我只能看到在python终端中引发警告的导入模块,但我无法将其跟踪到代码的确切行,只能跟踪到该行导入模块的。也许,可以在警告上添加断点或更改某些设置,或使用扩展?以下......
  • ffmpeg python 导致死锁
    我在使用ffmpegpython处理相机帧时遇到问题。我使用process.communicate()的第一种方法效果很好,但存在延迟问题。process=(ffmpeg.input('pipe:',format='rawvideo',pix_fmt='rgb24',s='{}x{}'.format(width,height))......
  • 将 HTTP 分块编码数据流代码片段从 Node.js 转换为 Python
    我有一个Node.js客户端代码,它将请求发送到HTTP服务器,然后连续接收分块编码数据。这是带有一些流量数据输出的Node.js代码。consthttp=require('http');constoptions={hostname:'...',path:'...',port:...,...};constreq=http.request(......
  • vsc python 调试器和 pylance 无法识别已安装的包
    我最近使用snowflake-connector-python在我的虚拟环境中安装了pipinstallsnowflake-connector-python[pandas]==2.7.6,当我在激活虚拟环境的情况下从命令行运行我的脚本时,它工作正常。我设置了与VSC解释器相同的虚拟环境,但尝试运行python调试器会引发异常......
  • 如何从python读取matlab持续时间对象
    我创建一个matlab持续时间对象并将其保存到.mat文件:timeend=seconds(123);save('time.mat',timeend,'-v7.3');然后我从python读取它:withh5py.File('time.mat','r')asf:var=f['timeend'][:]print(list(var))......
  • 通过 python 连接到 Snowflake 时出错“UnpicklingError: invalid load key, '\x00'
    我在使用snowflake.connector.connect通过python连接到snowflake时遇到以下错误importsnowflake.connector#pipinstallsnowflake-connector-python#iamgettingtheenvfrom.envfileistoredlocallycnx=snowflake.connector.connect(user=os.getenv('USER'),pass......
  • Python Selenium 单击 webdriverwait 与 find_element
    我无法理解这两个代码块之间的区别。发送点击在webdriverwait和find_elements中都有效。代码1fromseleniumimportwebdriverfromselenium.webdriver.common.byimportByfromselenium.webdriver.support.uiimportWebDriverWaitfromselenium.webdriver.suppo......
  • Python 问题 如何创建在 PDF 中注册为剪切线的专色?
    我正在开发一个项目,需要我在图像周围创建一条剪切线,但在任何RIP程序(例如Versaworks或Flexi)上将其注册为实际剪切线时遇到困难。我尝试了很多不同的方法python库可以帮助解决这个问题,但我无法让它工作。我希望它像我们在Illustrator中所做的那样,创建一条名为CutConto......
  • 使用Python时如何避免`setattr`(和`getattr`)?以及是否有必要避免
    如果我想向协议缓冲区中的字段添加一个在编译时未知的值,我目前正在做setattr我通常不喜欢使用setattr,因为它看起来不太安全。但是当我知道该对象是protobuf时,我认为这很好,因为我设置它的值必须是protobuf允许的类型。所以也许它并不是真的不安全?让我举......