AWS - 从Lambda / Node.js

时间:2018-01-05 19:40:07

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

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

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

这是否符合我的要求?也许Lambda / SNS不是一种可行的方式?如果是这样,你会推荐什么。

通过这个设置,当我的“main”函数完成运行时,我遇到问题,并且在我的循环中不会触发“sns.publish”。我假设因为我没有让它完成。但我不知道如何修复它,成为一个循环。

以下是我的Lambda函数的片段:

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");
};

感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

我认为更好的方法是使用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);
        }
    });
}

如您所见,对于lambda函数的调用,您不需要SNS。

重要提示:另一个建议是创建一个调用数组(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/

答案 1 :(得分:0)

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

  1. 开始调用sns.publish() 1000次
  2. 返回(通过context.succeed()
  3. 你没等等1000个电话完成!

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

    1. 开始调用sns.publish() 1000次
    2. sns.publish()的所有来电都已归还时,return。 (context.succeed已过时,我们应该使用callback()代替。
    3. 像这样......

      // 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));
      };