AWS - 从 Lambda 发送 1000 封电子邮件/Node.js
AWS - Sending 1000's of emails from Lambda / Node.js
我有一个由 SNS 触发的 "main" Lambda 函数。它从数据库中提取收件人列表,并需要根据模板向每个收件人发送一条消息,替换名字等内容。
我设置它的方式是我创建了另一个名为 "email-send" 的 Lambda 函数,它订阅了 "email-send" 主题。 "main" Lambda 然后循环遍历收件人列表,并使用适当的有效负载(发件人、收件人、主题、消息)将消息发布到 "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");
};
感谢您的帮助。
我认为更好的方法是使用 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);
}
});
看看这个link,我从中获得了很多关于 Lambda 调用的知识: https://cloudonaut.io/integrate-sqs-and-lambda-serverless-architecture-for-asynchronous-workloads/
您的代码正在执行此操作...
- 开始 调用
sns.publish()
1000 次
- Return(通过
context.succeed()
)
你没有等到那 1000 次通话结束!
您的代码应该做的是...
- 开始 调用
sns.publish()
1000 次
- 当对
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));
};
我有一个由 SNS 触发的 "main" Lambda 函数。它从数据库中提取收件人列表,并需要根据模板向每个收件人发送一条消息,替换名字等内容。
我设置它的方式是我创建了另一个名为 "email-send" 的 Lambda 函数,它订阅了 "email-send" 主题。 "main" Lambda 然后循环遍历收件人列表,并使用适当的有效负载(发件人、收件人、主题、消息)将消息发布到 "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");
};
感谢您的帮助。
我认为更好的方法是使用 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);
}
});
看看这个link,我从中获得了很多关于 Lambda 调用的知识: https://cloudonaut.io/integrate-sqs-and-lambda-serverless-architecture-for-asynchronous-workloads/
您的代码正在执行此操作...
- 开始 调用
sns.publish()
1000 次 - Return(通过
context.succeed()
)
你没有等到那 1000 次通话结束!
您的代码应该做的是...
- 开始 调用
sns.publish()
1000 次 - 当对
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));
};