【问题标题】:AWS - Sending 1000's of emails from Lambda / Node.jsAWS - 从 Lambda / Node.js 发送 1000 封电子邮件
【发布时间】:2018-06-15 15:46:41
【问题描述】:

我有一个由 SNS 触发的“主要”Lambda 函数。它从数据库中提取收件人列表,并且需要根据模板向每个收件人发送消息,替换名字等内容。

我的设置方式是我创建了另一个名为“email-send”的 Lambda 函数,该函数订阅了“email-send”主题。然后,“主”Lambda 循环遍历收件人列表并将消息发布到带有适当有效负载(来自、到、主题、消息)的“电子邮件发送”。这最终可能需要在一个批次中处理 1000 封电子邮件。

这是满足我要求的好方法吗?也许 Lambda/SNS 不可行?如果是的话,你会推荐什么。

使用此设置,当我的“main”函数完成运行并且不知何故“sns.publish”没有在我的循环中被触发时,我遇到了问题。我假设是因为我不会让它完成。但是我不确定如何解决它,因为它是一个循环。

这是我的 Lambda 函数的 sn-p:

exports.handler = (event, context, callback) => {
        // code is here to pull data into "data" array

        // process records
        for (var i = 0; i < data.length; i++) {
            var sns = new aws.SNS();
            sns.publish({
              Message: JSON.stringify({ from: data[i].from, to: data[i].to, subject: subject, body: body }),
              TopicArn: 'arn:aws:sns:us-west-2:XXXXXXXX:email-send'
            }, function(err, data) {
              if (err) {
                console.log(err.stack);
              } else {
                console.log('SNS pushed!');
              }
            });  
        }
        context.succeed("success");
};

感谢您的帮助。

【问题讨论】:

  • 您不需要 SNS 来调用另一个 Lambda 函数。只需使用 AWS API 调用它。
  • 调用“email-send”lambda 函数是我最初的方法。但是我在循环之后遇到了同样的问题。想法?

标签: amazon-web-services lambda amazon-sns amazon-ses


【解决方案1】:

您的代码正在执行此操作...

  1. 开始拨打sns.publish() 1000 次
  2. 返回(通过context.succeed()

您没有等待那 1000 个调用完成!

你的代码应该做的是......

  1. 开始拨打sns.publish() 1000 次
  2. 当所有对sns.publish() 的调用都返回时,则返回return。 (context.succeed 是旧的,所以我们应该改用callback())。

这样的……

// Instantiate the client only once instead of data.length times
const sns = new aws.SNS();

exports.handler = (event, context, callback) => {
  const snsCalls = []
  for (var i = 0; i < data.length; i++) {
    snsCalls.push(sns.publish({
      Message: JSON.stringify({
        from: data[i].from,
        to: data[i].to,
        subject: subject,
        body: body
      }),
      TopicArn: 'arn:aws:sns:us-west-2:XXXXXXXX:email-send'
    }).promise();
  }

  return Promise.all(snsCalls)
    .then(() => callback(null, 'Success'))
    .catch(err => callback(err));
};

【讨论】:

  • 感谢 dashmug,但我得到“.promise 不是函数”,我缺少一些依赖项?
【解决方案2】:

我认为更好的方法是使用 AWS Lambda API。

这样,您就不需要 SNS。

例如:

var lambda = new AWS.Lambda({region: AWS_REGION});
function invokeWorkerLambda(task, callback) {
    var params = {
        FunctionName: WORKER_LAMBDA_NAME,
        InvocationType: 'Event',
        Payload: JSON.stringify({.....})
    };
    lambda.invoke(params, function(err, data) {
        if (err) {
            console.error(err, err.stack);
            callback(err);
        } else {
            callback(null, data);
        }
    });
}

如您所见,您不需要 SNS 来调用 lambda 函数。

重要提示:另一个建议是创建一个调用数组 (functions),然后按如下方式执行它们:

async.parallel(invocations, function(err) {
    if (err) {
        console.error(err, err.stack);
        callback(err);
    }
});

看看这个链接,我从中获得了很多关于 Lambda 调用的知识: https://cloudonaut.io/integrate-sqs-and-lambda-serverless-architecture-for-asynchronous-workloads/

【讨论】:

  • 使用SNS代替直接调用Lambda的好处是SNS可以在失败时重试。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-17
  • 2020-03-02
  • 1970-01-01
  • 2011-08-07
  • 2011-02-08
  • 1970-01-01
相关资源
最近更新 更多