【问题标题】:django mail queue emails not sending with celerydjango 邮件队列电子邮件不使用 celery 发送
【发布时间】:2019-06-04 22:17:08
【问题描述】:

我在 Django 2.x

中使用Django Mail Queue

应用程序托管在 Heroku 上,并使用 redis 后端用于 Celery

settings.py 文件包含

##################
# CELERY STUFF
##################
BROKER_URL = os.getenv('REDIS_URL', 'redis://localhost:6379')
CELERY_RESULT_BACKEND = os.getenv('REDIS_URL', 'redis://localhost:6379')
CELERY_ACCEPT_CONTENT = ['application/json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'

#######################
# Django mail queue
#######################
MAILQUEUE_CELERY = True
MAILQUEUE_QUEUE_UP = False

并发送类似的电子邮件

new_message = MailerMessage()
new_message.subject = subject
new_message.to_address = to
new_message.from_address = from_email
new_message.content = text_content
new_message.html_content = html_content
new_message.app = 'Koober'
new_message.save()

在发送电子邮件时,它会保存在数据库中,并显示在管理页面上,但不会发送。

设置MAILQUEUE_CELERY = FalseMAILQUEUE_QUEUE_UP = False发送邮件成功。

但是如果出现异常,这会导致应用程序失败。这就是为什么我想使用 Celery 在后台发送电子邮件。

app/celery.py

from __future__ import absolute_import
import os
from celery import Celery
from django.conf import settings

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'koober.settings')
app = Celery('koober')

app.config_from_object('django.conf:settings')
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)


@app.task(bind=True)
def debug_task(self):
    print('Request: {0!r}'.format(self.request))

【问题讨论】:

  • Celery 日志中是否有错误?您是否尝试过使用 Celery 运行另一个简单的任务?
  • 我在 app/celery.py 处创建了一个 celery.py 文件(已更新)。如何记录芹菜日志。我是第一次使用 Celery
  • 我认为这可能是一个问题,因为 Celery 应该作为一个单独的进程运行。阅读如何在另一个终端选项卡中运行它docs.celeryproject.org/en/latest/getting-started/…
  • 您实际上是在发送排队的消息吗? python manage.py send_queued_messages?
  • @BurhanKhalid 这行得通。在 heroku heroku run python manage.py send_queued_messaged 中执行时。那么,我需要以 Cron 的身份运行命令吗?

标签: django celery django-celery


【解决方案1】:

来自documentation

可以将 cron 作业设置为以以下两种方式之一工作:使用管理 命令或 HTTP 请求。两种方法都运行邮件队列 抓取电子邮件并发送它们。为了减少负载,它只尝试发送 一次 30 封电子邮件。这个数字可以通过使用来改变 设置中的 MAILQUEUE_LIMIT

这个想法是消息排队等待发送,您必须手动触发工作人员发送消息。首选方法是通过运行send_queued_messages 管理命令来执行此操作:

python manage.py send_queued_messages

来自您的评论:

根据文档中的这一行 而不是使用 cron 作业 celery 任务工作者将在保存后尝试发送电子邮件。这 cron 作业将清理所有丢失的电子邮件。 我不需要运行 MAILQUEUE_CELERY = True.时的管理命令

默认情况下,应用程序不需要 celery 即可工作。它同步工作(同时)——这就是 django 的默认邮件功能的工作方式。

一旦应用程序到达发送邮件的代码,它就会尝试发送邮件并暂停,直到收到响应,然后继续处理其余的请求。

另一种选择是推迟发送电子邮件,而不是使用与 Web 相同的进程,而是同时使用辅助进程(工作者)。这就是设置MAILQUEUE_CELERY = True 时发生的情况。

如果你已经设置MAILQUEUE_QUEUE_UP = True,现在消息被接受但排队,你必须使用管理命令或cron来发送消息。

因此,如果您想立即发送消息,请将 MAILQUEUE_QUEUE_UP 设置为 False

如果要分批分批发送消息,请将MAILQUEUE_QUEUE_UP设置为True,然后设置一个cron作业运行管理命令。

【讨论】:

  • 但是我不能每次都运行管理命令。那么,我需要设置 Cron 作业来运行这个命令吗?
  • 按照文档Instead of using the cron job the celery task worker will attempt to send email when it’s saved. The cron job will clean up any emails that get lost.中的这一行,当MAILQUEUE_CELERY = True时,我不需要运行管理命令。
  • 我注意到当 MAILQUEUE_CELERY = True 时,即使是 mangement 命令也无法发送消息。甚至在从管理界面添加到队列之后。
  • 如果你使用同步模式(默认),那么它会自动发送。但是,您使用的是异步(排队),这意味着您需要通过管理命令手动发送批次。
  • 是的,我明白了你的想法。但就我而言,我有MAILQUEUE_CELERY = TrueMAILQUEUE_QUEUE_UP = False。因此,它应该在后台异步发送电子邮件,而不是排队等待管理命令。但是当MAILQUEUE_CELERY = True 时它既不发送保存也不发送管理命令
猜你喜欢
  • 2022-08-13
  • 2018-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-10
  • 2013-03-07
  • 2023-04-05
相关资源
最近更新 更多