Django 非阻塞邮件?使用 threading.thread 或 subprocess 的缺点?

5 投票
2 回答
1426 浏览
提问于 2025-04-16 16:57

我有一个用Django做的网站。用户在进行某些操作时,会给一组其他用户发送邮件。

当用户数量超过20个时,发送邮件的过程会让请求的处理时间增加1到3秒,这让我觉得不太好。我希望能用一种不阻塞的方式来发送邮件。

我知道RabbitMQ和Celery可以解决这个问题,但如果有200个用户,这样的方案感觉有点过于复杂了,而且还需要安装、理解和维护两个额外的应用。

我查了一些资料,发现使用threading.Thread和subprocess都可以实现不阻塞的调用。请问我是不是漏掉了什么简单的方法?使用threading.Thread或subprocess这两种方式有什么缺点吗?

谢谢,
特德

2 个回答

0

你早就解决了这个问题,但我刚遇到了同样的问题,这里有个快速的方法可以实现你提到的“简易异步邮件”:

http://djangosnippets.org/snippets/1864/

我添加了一个猴子补丁,具体描述可以在这里找到,这样就解决了线程异常的问题:

import threading
threading._DummyThread._Thread__stop = lambda x: 42

现在,正如人们所说,事情都搞定了。

9

把工作交给其他外部程序处理其实是个很好的选择,而且一旦你尝试过了,之后很可能还会继续这样做。Celery和RabbitMQ是不错的解决方案,而且它们已经准备好了。最近的RabbitMQ版本有一个不错的网页管理工具和一个管理API,这样管理起来会简单很多,而Celery在Django应用中也表现得很好。

你可以用子进程或线程来实现这个功能,但老实说,我觉得这不是个好习惯。不幸的是,如果你不想把工作交出去,这两种方法是最简单的选择。

如果你想走一种比较简单的“土办法”来处理异步邮件,你可以让你的应用把邮件直接保存到一个文件夹里,然后设置一个定时任务每分钟检查一次这个文件夹,把邮件发送出去。不过,这样做其实比用RabbitMQ和Celery要麻烦得多。

我建议你直接使用RabbitMQ和Celery。这并没有看起来那么复杂,而且从长远来看,这样做是值得的。

撰写回答