node.js - AWS SES : how to send a large amount of emails (> 10000 at a time)

标签 node.js aws-lambda amazon-ses

我正在构建一个电子邮件发送服务(lambda,Nodejs),它将同时向地址列表发送电子邮件。

由于要求:每个地址接收的邮件内容不同,我不能在一个请求中发送多封邮件,而是一封一封发送。

_array = ... // list of address + html content, > 10000 records
for (var i = 0; i < _array.length; i++) {
    var params = {
        Destination: {/* required */
            ToAddresses: [_array[i].email]
        },
        Message: {/* required */
            Body: { /* required */
                Html: {
                    Data: _array[i].html,
                    Charset: 'UTF-8'
                },
            },
            Subject: { /* required */
                Data: 'Your order detail', /* required */
                Charset: 'UTF-8'
            }
        },
        Source: "mytestemail@email.com"
    }

    let send = await ses.sendEmail(params).promise();

}

目前,我没有那么大的数据来测试,但我用 100-200 封电子邮件进行了测试,它正在运行,并且需要 15-40 秒才能完成发送电子邮件。从数学上讲,10000 需要超过 25 分钟才能完成任务。因此,这种方法不可扩展,因为 lambda 超时限制为 15 分钟

如有任何更好的方法或建议,我们将不胜感激。

编辑:

来自@Thales Minussi 的解决方案很棒,我实现了它并且它正在运行。我将其标记为答案,但我仍然欢迎所有解决此问题的最佳做法。快乐地分享、学习、编码

最佳答案

不推荐:可以做的是并行化 sendEmail 调用。因此,您可以创建一大堆 Promises,然后使用 await Promises.all(yourPromisesArray),这样 Node.js 就会根据可用的内核数量尽力优化流程您的 Lambda 函数运行的机器,意味着要充分利用它,您需要将 Lambda 的 RAM 内存设置为 3GB(机器与 RAM 的数量成正比,这意味着您设置的 RAM 越多越好您的代码运行的机器)。但这仍然有问题,因为现在我们谈论的是 10000 封电子邮件,但如果这个数字增长到 100000 会怎样? 1000000?它只是一个无法扩展到足以满足需求增长的解决方案,所以这还不够。另一件事是,如果出现问题(比如一个 Promise 失败),那么就很难恢复。

推荐:我的建议是使用 SQS 将创建电子邮件正文的函数与实际发送它的函数分离,说来话长简而言之,不是像上面那样调用 await ses.sendEmail(params).promise(),而是将此消息放入 SQS 队列(遵守每条消息 256KB 的限制)并且将另一个 Lambda 订阅到此 SQS 队列。每个 Lambda 可以从 SQS 读取最多 10 条消息(每条消息可以包含许多电子邮件),这将显着加快该过程,特别是因为默认情况下,您的 Lambda 函数将扩展以满足需求。

让我们做一个简单的数学运算:如果您向 SQS 发送 100 条消息,并且每条消息都有 10 封电子邮件,这意味着,在最佳情况下,将启动 10 个 Lambda,每个消耗一批 10 条消息,但作为每个消息包含 10 封电子邮件,每个 Lambda 将处理 100 封电子邮件,因此您将在眨眼间处理 1000 封电子邮件!

重要的是要注意,并非所有 Lambda 每次都会选取 10 个批处理,它们可能会选取较小的批处理,因此可能会同时启动 10 个以上的 Lambda 函数,但我认为你明白并行处理的思想

编辑:由于电子邮件可能包含大量负载(图像、长字符串等),我建议您只将相关信息发送到 SQS 队列以优化有效负载大小。如果您需要处理图像或一些预定义的模板,只需在 S3(或您可能使用的其他存储)中发送它们各自的位置,这样实际负责发送电子邮件的 Lambda 就是获取该信息的那个并将其添加到正文中。从本质上讲,您发送给 SQS 的消息应该只包含元数据,以使负载尽可能轻,这样您就可以充分利用 256KB 的限制。像这样的东西应该足以让你离开地面:

{
    "to": "to@email.com",
    "images": ["s3://bucket/image.jpg", "s3://bucket/image2.jpg"],
    "template": "s3://bucket/template.html"
}

关于node.js - AWS SES : how to send a large amount of emails (> 10000 at a time),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56127953/

相关文章:

node.js - 使用正则表达式按空格分割字符串

amazon-web-services - AWS SES + S3 : Send emails with attachment from S3

java - 调用 AWS Lambda Java 函数的 AWS 网关收到空正文

python - 代码中的 AWS 授权 - {"message": "The security token included in the request is invalid." }

email - 使用 AWS EC2 和 SES 时如何创建电子邮件帐户并设置电子邮件接收器?

amazon-web-services - AWS CloudFormation:AWS::Events::Rule - 输入模板

javascript - 如何在node.js中以非阻塞方式让连接等待?

php - Nodejs 和 PHP(客户端)

node.js - Firebase Admin SDK 用于从服务器登录用户

Python SMTP : emails being combined into one