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

44

我在Django上开发了一个应用,需要向各种使用情况下的用户发送大量电子邮件。出于明显的原因,我不想在应用程序中同步处理此操作。

请问有没有人可以推荐一款与Python良好集成或已在Django项目上使用过的消息队列服务器?我的技术栈还包括Apache、mod_python和MySQL。

8个回答

24

针对您的具体情况,因为只是一个电子邮件队列,我会采用简单方法,使用django-mailer。作为额外的好处,有其他可插拔的项目当在堆栈中看到django-mailer时,它们会聪明地利用它。

至于更一般的队列解决方案,我还没有尝试过任何一个,但这里有一些看起来更有趣的选择:

  1. pybeanstalk/beanstalkd
  2. Python接口到gearman(随着gearman的C语言版本发布,现在可能更加有趣)
  3. memcacheQ
  4. stomp
  5. Celery

3
针对这个特定需求,避免繁琐的操作,使用django-mailer; 它效果很好。 +1 - Carl Meyer
2
我现在正在尝试使用http://pypi.python.org/pypi/celery/,它看起来非常不错。 - Van Gale

14

目前我还没有找到“好”的解决方案。我的一些软实时要求更加严格(例如从一个纸盒上拍照并进行标记),因此或许这些方法中有一个足够快。我认为电子邮件可以等待几分钟。

  • 在数据库中创建一个“待办事项”列表,由cron作业处理。
  • 在数据库中创建一个“待办事项”列表,由永久轮询的守护进程处理。
  • 使用自定义守护程序,通过UDP数据包从web服务器接收通知(当前在生产环境中)。基本上是使用IP堆栈来处理队列的自己的排队系统。
  • 使用ActiveMQ作为消息代理 - 由于稳定性问题,这种方法不起作用。而且对我来说,Java Daemons通常比较笨重。
  • 在CouchDB中使用Update Triggers。非常好,但是Update Triggers不适合进行大量图像处理,所以不适用于我的问题。

到目前为止,我还没有尝试使用RabbitMQ和XMPP/ejabebrd来处理该问题,但它们已经在我的下一个尝试列表中。RabbitMQ在2008年获得了不错的Python连接性,并且有大量的XMPP库。

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


你尝试了哪个版本的ActiveMQ?在我工作的地方,我们基于它编写了整个NMS,并且在新版本上遇到了问题,但在旧的4.x版本上没有。 - fuzzy-waffle
我模糊地记得我们使用了4.x“稳定版”和测试版发布。 - max
6
顺便说一下,我们现在在生产中正在使用RabbitMQ,目前为止我们非常满意。 - max

6
Stompserver是一个不错的选择。它轻量级、易于安装,并且从Django/Python使用也很容易。
我们的系统在生产环境中使用stompserver发送电子邮件和异步处理其他任务。
Django将电子邮件保存到数据库,Django中的model.post_save处理程序发送事件到stompserver,stompserver将事件传递给一个消费者进程,该进程执行异步任务(发送电子邮件)。
它可以很好地扩展,因为您可以在运行时添加消费者进程-两个消费者可以发送两倍的电子邮件,并且消费者可以在不同的计算机上。一点小复杂性在于每个消费者需要自己的命名队列,因此Django需要知道可用的消费者数量,并以循环方式向每个队列发送事件。(同时监听同一队列的两个消费者都会收到每个消息=重复)。如果您只想要一个消费者进程,则这不是问题。
我们以前有不断轮询数据库以查找任务的进程,但发现即使没有需要处理的内容,它也会给系统增加很多负载。

1
你可能想看一下pymq。它是用Python编写的,与其客户端进行HTTP通信,并为队列提供了许多监控和管理选项。

1
只需将电子邮件添加到数据库中,然后编写另一个脚本,由某个任务调度程序实用程序(例如 cron)运行以发送电子邮件即可。

1

使用邮件基础设施解决这个问题有什么问题吗?比如,每个应用服务器都运行自己的邮件守护进程,它们将排队任何本地提交的邮件,然后转发到一个集中的邮件服务器,该服务器可以处理邮件重负载?


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)逐个弹出邮件并尝试发送。

0

如果您已经安装了MySQL,可以创建一个用作“待办事项列表”的表。

线程同步将作业添加到表中,批量任务会在完成后删除作业。

这样做的好处是不需要安装和学习更多的软件,并且只要您不发送大量电子邮件(如每秒钟>10封),它应该可以很好地作为持久性作业存储工具。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接