简体   繁体   English

AWS-从Lambda / Node.js发送1000封电子邮件

[英]AWS - Sending 1000's of emails from Lambda / Node.js

I have a "main" Lambda function that gets triggered by SNS. 我有一个由SNS触发的“主要” Lambda函数。 It pulls a list of recipients from the database and it needs to send each of them a message based on a template, replacing things like first name and such. 它从数据库中提取一个收件人列表,它需要根据模板向每个收件人发送一条消息,以替换名字等之类的信息。

The way I have it setup is I created another Lambda function called "email-send" which is subscribed to "email-send" topic. 设置的方式是我创建了另一个名为“电子邮件发送”的Lambda函数,该函数已订阅“电子邮件发送”主题。 The "main" Lambda then loops through the recipients list and publishes messages to "email-send" with a proper payload (from, to, subject, message). 然后,“主” Lambda遍历收件人列表,并将消息发布到具有适当有效负载(从,到主题,消息)的“电子邮件发送”。 This might eventually need to process 1000's of emails in a single batch. 最终可能需要单批处理1000封电子邮件。

Is this a good approach to my requirements? 这是满足我要求的好方法吗? Perhaps Lambda/SNS is not a way to go? 也许Lambda / SNS不是要走的路? If so, what would you recommend. 如果是这样,您会推荐什么。

With this setup I am running into issues when my "main" function finishes running and somehow "sns.publish" does not get triggered in my loop. 使用此设置,当我的“主要”功能完成运行并且以某种方式在循环中未触发“ sns.publish”时,我遇到了问题。 I assume because I am not letting it finish. 我想是因为我没有让它结束。 But I am not sure how to fix it, being a loop. 但是我不确定如何解决它,这是一个循环。

Here is the snippet from my Lambda function: 这是我的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");
};

Thanks for any assistance. 感谢您的协助。

I think that a better approach is using AWS Lambda API. 我认为更好的方法是使用AWS Lambda API。

That way, you don't need SNS. 这样,您就不需要SNS。

For example: 例如:

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

As you can see, you don't need SNS for lambda function's invocation. 如您所见,lambda函数的调用不需要SNS。

Important: Another suggestion is to create an Array of invocations ( functions ) and later execute them as follow: 重要提示:另一个建议是创建一个调用数组( functions ),然后按如下所示执行它们:

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

Take a look at this link where I got a lot of knowledge about Lambda invocation: https://cloudonaut.io/integrate-sqs-and-lambda-serverless-architecture-for-asynchronous-workloads/ 看看这个链接,我在其中获得了很多有关Lambda调用的知识: https : //cloudonaut.io/integrate-sqs-and-lambda-serverless-architecture-for-asynchronous-workloads/

Your code is doing this... 您的代码正在执行此操作...

  1. Begin calling sns.publish() 1000 times 开始调用sns.publish() 1000次
  2. Return (through context.succeed() ) 返回(通过context.succeed()

You didn't wait for those 1000 calls to finish! 您没有等待那1000个电话结束!

What your code should do is... 您的代码应该做的是...

  1. Begin calling sns.publish() 1000 times 开始调用sns.publish() 1000次
  2. When all calls to sns.publish() has returned, then return . 返回对sns.publish()所有调用后,请return ( context.succeed is old so we should use callback() instead). context.succeed很旧,因此我们应该使用callback()代替)。

Something like this... 像这样

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 从AWS Lambda Node.JS流式传输并压缩到S3 - Stream and zip to S3 from AWS Lambda Node.JS 使用Node.js处理程序发送和发送电子邮件时出现AWS Lambda NetworkingError - AWS Lambda NetworkingError when sending and email with a Node.js handler 使用node.js将JSON从AWS Lambda保存到AWS S3 - Save a JSON from AWS Lambda to AWS S3 with node.js Node.js Lambda函数中的AWS S3 ListObjects - AWS S3 ListObjects in Node.js Lambda Function 将模块从 S3 动态加载到 node.js AWS lambda 中 - Loading modules into node.js AWS lambda dynamically from S3 如何使用 Node.js 将文件从 AWS Lambda 中的 /tmp 文件夹上传到 S3 - How to upload a file to S3 from the /tmp folder in AWS Lambda using Node.js 从在本地系统而非 S3 上运行的 node.js 应用程序调用 AWS Lambda - Invoke AWS Lambda from a node.js app running on local system not S3 如何使用Node.js从AWS Lambda的/ tmp文件夹将WAV文件上传到S3 - How to upload a WAV file to S3 from the /tmp folder in AWS Lambda using Node.js 如何使用 Node.js 在 AWS Lambda 函数上播放来自 S3 Bucket 的音频文件? - How to play an audio file from S3 Bucket on AWS Lambda function using Node.js? 如何使用 Node.js AWS Lambda ZC1C425268E68385D1AB5074C17A94 从 S3 读取 CSV 数据 - How to read CSV data from S3 using Node.js AWS Lambda function
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM