[英]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... 您的代码正在执行此操作...
sns.publish()
1000 times sns.publish()
1000次 context.succeed()
) context.succeed()
) You didn't wait for those 1000 calls to finish! 您没有等待那1000个电话结束!
What your code should do is... 您的代码应该做的是...
sns.publish()
1000 times sns.publish()
1000次 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.