2

我有一个流程,每周发送大约 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 queueor更好celery

我正在使用Amazon Simple Emails ServiceSES)。

4

1 回答 1

1

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

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

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

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

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

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

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

它是为此而设计的,它经过了尝试、测试、工作......

所以这对你来说是最简单的路径。

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

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

于 2018-08-14T16:16:08.630 回答