关于Python / Django和消息队列的建议

时间:2009-01-18 10:42:54

标签: python django message-queue

我在Django中有一个应用程序,需要在各种用例中向用户发送大量电子邮件。我不想出于显而易见的原因在应用程序中同步处理这个问题。

有没有人建议消息排队服务器与Python完美集成,或者他们在Django项目中使用过?我的堆栈的其余部分是Apache,mod_python,MySQL。

9 个答案:

答案 0 :(得分:24)

在您的特定情况下,它只是一个电子邮件队列,我会轻松地使用django-mailer。作为一个不错的方面,还有其他可插拔的项目,当他们在堆栈中看到它时,它们足够聪明,可以利用django-mailer。

至于更一般的队列解决方案,我还没有能够尝试其中任何一个,但这里有一个对我来说更有趣的列表:

  1. pybeanstalk/beanstalkd
  2. python interface to gearman(现在发布C version of gearman可能会更有趣)
  3. memcacheQ
  4. stomp
  5. Celery

答案 1 :(得分:14)

到目前为止,我没有找到任何“好”的解决方案。我有一些更严格的软实时要求(从标签纸板箱拍照)所以可能其中一种方法足够快。我假设电子邮件可以等几分钟。

  • 由cron作业处理的数据库中的“待办事项列表”。
  • 数据库中的“待办事项列表”由守护程序永久监视。
  • 使用自定义守护程序,该守护程序由Web服务器通过UDP数据包通知(在今天的生产中)。基本上我自己的Queing系统带有用于处理队列的IP堆栈。
  • Using ActiveMQ as a message broker - 由于稳定性问题,这没有成功。对我来说,Java守护进程通常有些丰满
  • 在CouchDB中使用更新触发器。不错但更新触发器并不意味着要进行繁重的图像处理,因此不适合我的问题。

到目前为止,我还没有尝试使用RabbitMQ和XMPP / ejabebrd来处理这个问题,但是我们列出了下一个要尝试的东西。 RabbitMQ在2008年获得了不错的Python连接,并且有大量的XMPP库。

但是,您可能只需要在本地计算机上配置正确的邮件服务器。这可能允许您将邮件同步转储到本地邮件服务器中,从而使整个软件堆栈更加简单。

答案 2 :(得分:6)

Stompserver是个不错的选择。它轻巧,易于安装,易于使用Django / python。

我们有一个系统在生产中使用stompserver发送电子邮件并异步处理其他作业。

Django将电子邮件保存到数据库,Django中的model.post_save处理程序将事件发送到stompserver,stompserver将事件传递给执行异步任务的消费者进程(发送电子邮件)。

它可以很好地扩展,因为你可以在运行时添加消费者进程 - 两个消费者可以发送两倍的电子邮件,而消费者可以在单独的机器上。一个轻微的复杂问题是每个消费者都需要自己的命名队列,因此Django需要知道有多少消费者可用,并以循环方式向每个队列发送事件。 (两个听取同一队列的消费者都会得到每条消息=重复)。如果您只想要一个消费者流程,那么这不是问题。

我们以前有一些进程可以连续轮询数据库以查找作业,但发现它为系统增加了很多负载,即使不需要处理任何内容也是如此。

答案 3 :(得分:1)

只需将电子邮件添加到数据库,然后编写另一个由任务调度程序实用程序(cron想到)运行的脚本来发送电子邮件。

答案 4 :(得分:1)

您可能需要查看pymq。它是用python编写的,与它的客户端进行HTTP协商,并为队列提供了大量的监控和管理选项。

答案 5 :(得分:1)

使用邮件基础设施解决这个问题有什么不对吗?比如,每个应用服务器都运行自己的邮件守护进程,这些守护进程将对任何本地提交的邮件进行排队,这些邮件会转发到集中邮件服务器,从而可以完成邮件繁重的工作?

答案 6 :(得分:1)

http://www.snakemq.net/也可以正常使用

答案 7 :(得分:0)

如果你已经安装了MySQL,你可以创建一个表作为各种各样的“待办事项列表”。

线程同步向表中添加作业,批处理任务在完成后删除作业。

这样,就没有必要安装和学习更多的软件,只要你没有发送批次的电子邮件(例如> 10 /秒)。

答案 8 :(得分:0)

这是一个懒惰但正确和适当的解决方案。使用以下数据库表作为队列。

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
);

发件人应该在此表的末尾插入新行。

设置工作线程从另一端(最低id)一次弹出一个邮件并尝试发送它们。