为什么我的 Lambda 函数一次调用会发送两次 SQS 消息?
Why does my Lambda function send an SQS message twice with one call?
我只需要向一个标准(不是FIFO,但与问题无关)SQS队列传递消息,一次和一次打电话。
但是,下面的代码是通过 1 次调用发送 2 条消息。
const AWS = require('aws-sdk')
AWS.config.update({region: process.env.AWS_REGION})
const sqs = new AWS.SQS({apiVersion: '2012-11-05'});
async function sendToSQSEvent(body,attributes=null){
var m_body
if (attributes != null)
{
m_body = {
body : body,
attributes : attributes
};
}
else{
m_body = body;
}
m_body = JSON.stringify(m_body);
var params = {
// DelaySeconds: 0, <-- i try but only delay reception
MessageAttributes: {
"Title": {
DataType: "String",
StringValue: "TIME_OUT"
},
"Author": {
DataType: "String",
StringValue: "LAMBDA_IN"
},
},
MessageBody: m_body,
QueueUrl: "https://my_url/sqs"
};
console.log('_________CALL_______________');
var r = await sqs.sendMessage(params, function(err, data) {
if (err) {
console.log("Error", err);
} else {
console.log("Success", data.MessageId ,data);
}
}).promise(console.log("_________in promise___________"));
console.log("___end")
}
exports.handler = async (event, context) => {
await sendToSQSEvent(event)
};
控制台输出为:
START RequestId: RequestId Version: $LATEST
2021-10-11T06:23:52.992Z RequestId INFO _________CALL_______________
2021-10-11T06:23:53.425Z RequestId INFO _________in promise___________
2021-10-11T06:23:53.728Z RequestId INFO Success ********-****-****-****-*********b4f {
ResponseMetadata: { RequestId: '********-****-****-****-*********89d' },
MD5OfMessageBody: '********************************8f',
MD5OfMessageAttributes: '***********************1b0',
MessageId: '********-****-****-****-*********b4f'
}
2021-10-11T06:23:53.786Z RequestId INFO ___end
2021-10-11T06:23:53.807Z RequestId INFO Success ********-****-****-****-*********665 {
ResponseMetadata: { RequestId: '********-****-****-****-********835' },
MD5OfMessageBody: '***********************28f',
MD5OfMessageAttributes: '***********************1b0',
MessageId: '********-****-****-****-*********665'
}
END RequestId: RequestId
问题是什么?
它会在您混音时发送两次消息同步 callbacks (function(err, data)
) with asynchronous promises (await
, async function sendToSQSEvent(...)
).
您可以看到这一点,因为 CloudWatch 正在记录 2 sqs.sendMessage(...)
个响应。
我建议坚持使用后者。
这应该是您的 SQS sendMessage
逻辑,它 returns 您的处理程序的承诺对象。
return sqs.sendMessage(params).promise();
然后您可以检查处理程序中的响应:
exports.handler = async (event, context) => {
try {
var data = await sendToSQSEvent(event)
console.log("Success", data.MessageId ,data);
}
catch (err){
console.log("Error", err);
}
};
这应该是最终的工作结果:
const AWS = require('aws-sdk')
AWS.config.update({
region: process.env.AWS_REGION
})
const sqs = new AWS.SQS({
apiVersion: '2012-11-05'
});
async function sendToSQSEvent(body, attributes = null) {
var m_body
if (attributes != null) {
m_body = {
body: body,
attributes: attributes
};
} else {
m_body = body;
}
m_body = JSON.stringify(m_body);
var params = {
MessageAttributes: {
"Title": {
DataType: "String",
StringValue: "TIME_OUT"
},
"Author": {
DataType: "String",
StringValue: "LAMBDA_IN"
},
},
MessageBody: m_body,
QueueUrl: "https://my_url/sqs"
};
return sqs.sendMessage(params).promise();
}
exports.handler = async (event, context) => {
try {
var data = await sendToSQSEvent(event)
console.log("Success", data.MessageId ,data);
}
catch (err){
console.log("Error", err);
}
};
我只需要向一个标准(不是FIFO,但与问题无关)SQS队列传递消息,一次和一次打电话。
但是,下面的代码是通过 1 次调用发送 2 条消息。
const AWS = require('aws-sdk')
AWS.config.update({region: process.env.AWS_REGION})
const sqs = new AWS.SQS({apiVersion: '2012-11-05'});
async function sendToSQSEvent(body,attributes=null){
var m_body
if (attributes != null)
{
m_body = {
body : body,
attributes : attributes
};
}
else{
m_body = body;
}
m_body = JSON.stringify(m_body);
var params = {
// DelaySeconds: 0, <-- i try but only delay reception
MessageAttributes: {
"Title": {
DataType: "String",
StringValue: "TIME_OUT"
},
"Author": {
DataType: "String",
StringValue: "LAMBDA_IN"
},
},
MessageBody: m_body,
QueueUrl: "https://my_url/sqs"
};
console.log('_________CALL_______________');
var r = await sqs.sendMessage(params, function(err, data) {
if (err) {
console.log("Error", err);
} else {
console.log("Success", data.MessageId ,data);
}
}).promise(console.log("_________in promise___________"));
console.log("___end")
}
exports.handler = async (event, context) => {
await sendToSQSEvent(event)
};
控制台输出为:
START RequestId: RequestId Version: $LATEST
2021-10-11T06:23:52.992Z RequestId INFO _________CALL_______________
2021-10-11T06:23:53.425Z RequestId INFO _________in promise___________
2021-10-11T06:23:53.728Z RequestId INFO Success ********-****-****-****-*********b4f {
ResponseMetadata: { RequestId: '********-****-****-****-*********89d' },
MD5OfMessageBody: '********************************8f',
MD5OfMessageAttributes: '***********************1b0',
MessageId: '********-****-****-****-*********b4f'
}
2021-10-11T06:23:53.786Z RequestId INFO ___end
2021-10-11T06:23:53.807Z RequestId INFO Success ********-****-****-****-*********665 {
ResponseMetadata: { RequestId: '********-****-****-****-********835' },
MD5OfMessageBody: '***********************28f',
MD5OfMessageAttributes: '***********************1b0',
MessageId: '********-****-****-****-*********665'
}
END RequestId: RequestId
问题是什么?
它会在您混音时发送两次消息同步 callbacks (function(err, data)
) with asynchronous promises (await
, async function sendToSQSEvent(...)
).
您可以看到这一点,因为 CloudWatch 正在记录 2 sqs.sendMessage(...)
个响应。
我建议坚持使用后者。
这应该是您的 SQS sendMessage
逻辑,它 returns 您的处理程序的承诺对象。
return sqs.sendMessage(params).promise();
然后您可以检查处理程序中的响应:
exports.handler = async (event, context) => {
try {
var data = await sendToSQSEvent(event)
console.log("Success", data.MessageId ,data);
}
catch (err){
console.log("Error", err);
}
};
这应该是最终的工作结果:
const AWS = require('aws-sdk')
AWS.config.update({
region: process.env.AWS_REGION
})
const sqs = new AWS.SQS({
apiVersion: '2012-11-05'
});
async function sendToSQSEvent(body, attributes = null) {
var m_body
if (attributes != null) {
m_body = {
body: body,
attributes: attributes
};
} else {
m_body = body;
}
m_body = JSON.stringify(m_body);
var params = {
MessageAttributes: {
"Title": {
DataType: "String",
StringValue: "TIME_OUT"
},
"Author": {
DataType: "String",
StringValue: "LAMBDA_IN"
},
},
MessageBody: m_body,
QueueUrl: "https://my_url/sqs"
};
return sqs.sendMessage(params).promise();
}
exports.handler = async (event, context) => {
try {
var data = await sendToSQSEvent(event)
console.log("Success", data.MessageId ,data);
}
catch (err){
console.log("Error", err);
}
};