【问题标题】:Why does my Lambda function send an SQS message twice with one call?为什么我的 Lambda 函数一次调用会发送两次 SQS 消息?
【发布时间】:2021-11-29 23:02:50
【问题描述】:

我只需要将消息传递到标准(不是 FIFO,但与问题无关)SQS 队列,一次one 调用。

但是,下面的代码是通过 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

有什么问题?

【问题讨论】:

  • 这是你的整个 lambda 吗?它不应该发送 2
  • @ErmiyaEskandary 1) 是的,我只是格式化 exports.handler = async (event, context) 的事件。 2) 这不是一个解决方案,我的 SQS 什么都没有,控制台什么也没有。谢谢你试图帮助我
  • 嗯,好的 - 你能用你的完整代码更新这个问题,以便它可以重现吗?
  • @ErmiyaEskandary 完成 :) 如果你有什么发现就告诉我

标签: javascript amazon-web-services aws-lambda es6-promise amazon-sqs


【解决方案1】:

当您将 同步 callbacks (function(err, data)) 与 异步 promises (await, async function sendToSQSEvent(...)) 混合时,它会发送两次消息.

您可以看到这一点,因为 CloudWatch 正在记录 2 个 sqs.sendMessage(...) 响应。

我建议坚持后者。


这应该是您的 SQS sendMessage 逻辑,它为您的处理程序返回一个承诺对象。

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);
    }
};

【讨论】:

  • 干得好!现在看起来不错,但我不明白为什么? JS问题?谢谢!!
  • @jchenaud 正在用解释更新答案:) - 这有意义吗?不客气!
  • 完美!!谢谢
猜你喜欢
  • 2023-02-17
  • 2018-04-04
  • 1970-01-01
  • 2021-07-21
  • 2020-12-14
  • 2020-05-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多