Skip to main content
 首页 » 编程设计

python之在 django 和 aws 中使用 crontab 发送数千封电子邮件

2024年12月31日35qlqwjy

我有一个流程,每周发送一次大约 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)。

请您参考如下方法:

这里有两个不同的问题要处理:

首先,虽然发送 1500 封电子邮件非常容易,但是否会收到这 1500 封电子邮件却存在复杂的现实。您的电子邮件很容易被阻止或转移到垃圾邮件文件夹。您的整个域可能会被某些邮件服务阻止。为了限制这些困难的可能性,您需要正确设置 DKIM 和 SPF 记录。商业邮件发件人还可以做其他事情来保持顺利。因此,如果您对接受该挑战不感兴趣,最好使用像 SES 这样的专业服务。

当然,您也可以只使用 postfix 或任何其他邮件中继软件在本地设置您自己的邮件服务器,甚至是在同一台机器上。设置您自己的 DNS 记录并将邮件直接发送给收件人,无需 SES 或任何其他人来处理..但是您必须处理任何垃圾邮件拦截器问题。

其次,假设您使用 SES,您必须确保所有电子邮件都安全地从您自己发送到亚马逊。这就是麻烦来的地方。您不想生成一半的电子邮件并将它们发送出去,然后由于假设网络中断,出现问题......并且无法仅发送那些没有发送的电子邮件重新发送所有。编写完美的代码可能有点棘手。

从技术上讲,最简单的解决方案是安装本地 SMTP 中继服务器(例如 postfix),并将 Amazon 配置为“智能主机”。配置 django 使用“localhost”作为它的 SMTP 服务器。

有了它,当您的 cron 作业运行时,它只需要几秒钟,因为所有电子邮件都直接进入本地驱动器上的 postfix 目录并在那里排队。

然后是postfix,因为它配置了SES的SMTP服务器作为它的smarthost(有时也叫smart relay),不会直接发送任何邮件给收件人,而是将所有的邮件转发给SES,传递给最终的收件人.如果这样做有任何问题,postfix(或您喜欢的任何邮件中继软件)将重试每条消息,直到一切顺利。

它就是为此而生,经过尝试、测试、有效...

所以这对您来说是最简单的方法。

如果您选择使用 SES REST API,那么您的代码有责任确保将每条消息准确地发送到亚马逊一次且仅发送一次。如果您遍历 1000 封电子邮件,然后出现网络故障或崩溃,并且您未能发送最后 500 封电子邮件,那么您的代码将无法从中恢复而无需再次重新发送前 1000 封电子邮件。为此,是的,排队系统很有用。 Celery 或 RabbitMQ 本身就可以工作。或者只是通过在您的数据库中存储需要发送哪些消息的记录然后在发送每封电子邮件时删除这些记录来制作一个队列。

但是编写在任何情况下都能完美运行的代码可能很棘手。有时重新发明轮子是可以的。有时您需要更好的轮子 :) 但在这种情况下,我认为您最好使用 SMTP 中继服务器。