javascript - 为什么我的 Lambda 函数一次调用会发送两次 SQS 消息?
问题描述
我只需要一次调用一次将消息传递到标准(不是 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
问题是什么?
解决方案
当您将同步 回调( function(err, data)
) 与异步 承诺( await
, async function sendToSQSEvent(...)
) 混合时,它会发送两次消息。
您可以看到这一点,因为 CloudWatch 正在记录 2 个sqs.sendMessage(...)
响应。
我建议坚持后者。
这应该是您的 SQSsendMessage
逻辑,它为您的处理程序返回一个承诺对象。
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);
}
};
推荐阅读
- mocking - NSubstitute 无法确定项目“运行所有测试”时要使用的参数规范
- android - FCM Android - 点击通知 - 打开网页视图
- java - JAXB 无法将值转换为 BigDecimal
- c++ - 具有 N 列和 N 行的矩阵,列必须具有 N-1 , N-2 等值
- notifications - PWA关闭时如何接收点击通知数据?
- javascript - 使用 JQuery 和 Ajax 淡化 html 页面的问题
- rest - 在 http 请求中设置 grpc 元数据
- flutter - 没有材料设计或库比蒂诺定制的颤振?
- python - tkinter 中的打包和网格
- android - 使 NestedScrollView 中的工具栏不可滚动