【发布时间】:2018-08-15 00:29:43
【问题描述】:
我有一个流程,每周发送大约 1500 封邮件。
我在django 命令中拥有它的过程,我计划将其放入crontab。该过程有一个循环,在该循环中验证用户是否想要接收电子邮件以及接收的语言,例如:
for user in users:
# Check if user accept emails
if user['send_mail']:
# Get language to email
lang = ""
if user['lang'] == "es":
lang = "es"
elif user['lang'] == "fr":
lang = "fr"
else:
lang = "en"
email = user['email']
# Send email
send_mail()
1500 封邮件并不多,但我想让它具有可扩展性,因为邮件的数量取决于平台的注册用户数量。
我不知道它现在是否可以扩展或者使用redis queue 或celery 更好。
我正在使用Amazon Simple Emails Service (SES)。
【问题讨论】:
-
请不要使用队列发送电子邮件。电子邮件系统(根据 SMTP 规范的本质)是一个巨大的队列。有两种方法可以解决这个问题:要么在此框上使用本地邮件守护程序,将电子邮件转发出去并处理重试,要么使用为您提供休息接口(如 SES)的系统,它将为您重试。 Celery/Redis 不适合这项工作,因为 SMTP 从重试的角度来看需要大量客户端,而您不想自己编写代码。
-
@MatthewStory 我根本不同意,我不禁觉得你错过了问题的重点。是的,电子邮件是一种队列,但 SES 是一种 API,访问它需要时间;如果您尝试在 Django 视图中执行 1500 次 API 调用,它将超时。
-
@DanielRoseman 他正在将其移至 crontab ......那你为什么要使用 celery?另外,为什么您从根本上不同意?电子邮件不是一种队列,它们实际上是一个特定于域的优先级队列,具有非常粗糙的重试规范。
-
@MatthewStory 感谢您的回答。你能再解释一下吗:“这里有两种方法:要么在这个盒子上使用一个本地邮件守护程序,它将转发电子邮件并处理重试,要么使用一个为你提供休息接口的系统(如 SES)这将为您重试”我不明白现在这样是否可以,或者我是否必须进行更改以使其可扩展?谢谢!
-
@YannicHamann 我将在今天晚些时候尝试撰写对此的答案以更详细地介绍它,但简短的回答是,根据定义,SMTP 是一个异步任务队列,它具有非常具体和复杂的重试规则客户端必须实现,因此使用 celery 是多余的,并且还可能导致不正确的客户端实现。这就是为什么我通常更喜欢使用本地中继邮件程序,保证本地交付(如 nullmailer)或使用来自 cron 的 REST 接口(如 SendGrid 或 SES)。
标签: python django amazon-web-services amazon-simple-email-service