AWS Lambda 在向 SQS 发送消息之前完成
AWS Lambda finish before sending message to SQS
我正在 运行在 AWS 上使用 "Node.JS" lambda 向 SQS 发送消息。
出于某种原因,SQS 回调函数每两次调用只执行一次。看起来 运行 使 lambda 完成的线程完成了 运行(因为它不是对 SQS 的同步调用,也不能 return 一个 Future),因此 lambda 没有t "stay alive" 用于执行回调。
如何解决这个问题并让 lambda 等待 SQS 回调执行?
这是我的 lambda 代码:
exports.handler = async (event, context) => {
// Set the region
AWS.config.update({region: 'us-east-1'});
// Create an SQS service object
var sqs = new AWS.SQS({apiVersion: '2012-11-05'});
const SQS_QUEUE_URL = process.env.SQS_QUEUE_URL;
var params = {
MessageGroupId: "cv",
MessageDeduplicationId: key,
MessageBody: "My Message",
QueueUrl: SQS_QUEUE_URL
};
console.log(`Sending notification via SQS: ${SQS_QUEUE_URL}.`);
sqs.sendMessage(params, function(err, data) { //<-- This function get called about one time every 4 lambda calls
if (err) {
console.log("Error", err);
context.done('error', "ERROR Put SQS");
} else {
console.log("Success", data.MessageId);
context.done(null,'');
}
});
};
您应该坚持基于回调的方法,或者基于承诺的方法。我推荐你使用后者:
exports.handler = async (event, context) => {
// Set the region
AWS.config.update({region: 'us-east-1'});
// Create an SQS service object
var sqs = new AWS.SQS({apiVersion: '2012-11-05'});
const SQS_QUEUE_URL = process.env.SQS_QUEUE_URL;
var params = {
MessageGroupId: "cv",
MessageDeduplicationId: key,
MessageBody: "My Message",
QueueUrl: SQS_QUEUE_URL
};
console.log(`Sending notification via SQS: ${SQS_QUEUE_URL}.`);
try {
await sqs.sendMessage(params).promise(); // since your handler returns a promise, lambda will only resolve after sqs responded with either failure or success
} catch (err) {
// do something here
}
};
P.S。在处理程序中实例化 aws 类 在 lambda 环境中不是一个好主意,因为它会增加冷启动时间。最好将 new AWS.SQS(...)
动作移出处理程序,AWS.config.update()
也移出,因为这些动作将在每次调用处理程序时执行,但您确实需要它们只执行一次。
我正在 运行在 AWS 上使用 "Node.JS" lambda 向 SQS 发送消息。 出于某种原因,SQS 回调函数每两次调用只执行一次。看起来 运行 使 lambda 完成的线程完成了 运行(因为它不是对 SQS 的同步调用,也不能 return 一个 Future),因此 lambda 没有t "stay alive" 用于执行回调。
如何解决这个问题并让 lambda 等待 SQS 回调执行?
这是我的 lambda 代码:
exports.handler = async (event, context) => {
// Set the region
AWS.config.update({region: 'us-east-1'});
// Create an SQS service object
var sqs = new AWS.SQS({apiVersion: '2012-11-05'});
const SQS_QUEUE_URL = process.env.SQS_QUEUE_URL;
var params = {
MessageGroupId: "cv",
MessageDeduplicationId: key,
MessageBody: "My Message",
QueueUrl: SQS_QUEUE_URL
};
console.log(`Sending notification via SQS: ${SQS_QUEUE_URL}.`);
sqs.sendMessage(params, function(err, data) { //<-- This function get called about one time every 4 lambda calls
if (err) {
console.log("Error", err);
context.done('error', "ERROR Put SQS");
} else {
console.log("Success", data.MessageId);
context.done(null,'');
}
});
};
您应该坚持基于回调的方法,或者基于承诺的方法。我推荐你使用后者:
exports.handler = async (event, context) => {
// Set the region
AWS.config.update({region: 'us-east-1'});
// Create an SQS service object
var sqs = new AWS.SQS({apiVersion: '2012-11-05'});
const SQS_QUEUE_URL = process.env.SQS_QUEUE_URL;
var params = {
MessageGroupId: "cv",
MessageDeduplicationId: key,
MessageBody: "My Message",
QueueUrl: SQS_QUEUE_URL
};
console.log(`Sending notification via SQS: ${SQS_QUEUE_URL}.`);
try {
await sqs.sendMessage(params).promise(); // since your handler returns a promise, lambda will only resolve after sqs responded with either failure or success
} catch (err) {
// do something here
}
};
P.S。在处理程序中实例化 aws 类 在 lambda 环境中不是一个好主意,因为它会增加冷启动时间。最好将 new AWS.SQS(...)
动作移出处理程序,AWS.config.update()
也移出,因为这些动作将在每次调用处理程序时执行,但您确实需要它们只执行一次。