我在 Django 中有一个应用程序,需要在各种用例中向用户发送大量电子邮件。出于显而易见的原因,我不想在应用程序中同步处理这个问题。
有没有人对与 Python 很好集成的消息队列服务器有任何建议,或者他们已经在 Django 项目中使用过?我的堆栈的其余部分是 Apache、mod_python、MySQL。
我在 Django 中有一个应用程序,需要在各种用例中向用户发送大量电子邮件。出于显而易见的原因,我不想在应用程序中同步处理这个问题。
有没有人对与 Python 很好集成的消息队列服务器有任何建议,或者他们已经在 Django 项目中使用过?我的堆栈的其余部分是 Apache、mod_python、MySQL。
在您的特定情况下,它只是一个电子邮件队列,我会采取简单的方法并使用django-mailer。作为一个不错的好处,还有其他可插入的项目足够聪明,可以在他们在堆栈中看到 django-mailer 时利用它。
至于更通用的队列解决方案,我还没有尝试过其中的任何一个,但这里列出了一些对我来说更有趣的解决方案:
到目前为止,我还没有找到“好的”解决方案。我有一些更严格的软实时要求(从贴有标签的纸板箱中拍照)所以可能其中一种方法对您来说足够快。我假设电子邮件可以等待几分钟。
到目前为止,我还没有尝试过 RabbitMQ 和 XMPP/ejabebrd 来处理这个问题,但它们在我接下来要尝试的事情列表中。RabbitMQ 在 2008 年获得了不错的 Python 连接,并且有大量的 XMPP 库。
但也许您只需要在本地机器上正确配置邮件服务器。这可能允许您将邮件同步转储到本地邮件服务器,从而使您的整个软件堆栈更加简单。
Stompserver 是一个不错的选择。它是轻量级的,易于安装且易于从 Django/python 使用。
我们有一个系统在生产中使用 stompserver 来异步发送电子邮件和处理其他工作。
Django 将电子邮件保存到数据库中,Django 中的 model.post_save 处理程序将事件发送到 stompserver 并且 stompserver 将事件传递给执行异步任务(发送电子邮件)的消费者进程。
它可以很好地扩展,因为您可以在运行时添加消费者进程——两个消费者可以发送两倍的电子邮件,消费者可以在不同的机器上。一个小麻烦是每个消费者都需要自己的命名队列,因此 Django 需要知道有多少消费者可用,并以循环方式向每个队列发送事件。(在同一个队列上监听的两个消费者都将得到每个消息 = 重复)。如果您只想要一个消费者进程,那么这不是问题。
我们以前的进程会不断地轮询数据库中的作业,但发现它给系统增加了很多负载,即使不需要处理任何东西。
只需将电子邮件添加到数据库中,然后编写另一个由某些任务计划程序实用程序(想到 cron)运行的脚本来发送电子邮件。
您可能想看看pymq。它是用 python 编写的,与它的客户端进行 HTTP 通信,并允许对队列进行大量监控和管理选项。
使用邮件基础设施解决这个问题有什么问题吗?就像,每个运行自己的邮件守护进程的应用服务器都会将任何本地提交的邮件排队,然后转发到可以处理邮件繁重的集中式邮件服务器?
如果您已经安装了 MySQL,您可以创建一个表以用作各种“待办事项列表”。
线程同步地将作业添加到表中,批处理任务在作业完成后删除它们。
这样,就无需安装和学习更多软件,只要您不发送大量电子邮件(例如 >10/秒),它就可以作为持久的作业存储正常工作。
这是一个懒惰但正确且充分的解决方案。使用以下数据库表作为队列。
drop table if exists mailqueue;
create table mailqueue (
id bigint primary key,
subject text not null,
body mediumtext not null,
from varchar(255) not null,
to varchar(255) not null
);
发件人应将新行插入此表的末尾。
Setup worker threads to pop mails one at a time from the other end (lowest id) and try to send them.