从SQS FIFO队列中删除消息:收据句柄已过期

时间:2017-10-09 07:22:20

标签: amazon-web-services queue amazon-sqs

我切换到FIFO队列,当我尝试从队列中删除消息时收到此错误消息

Value {VALUE} for parameter ReceiptHandle is invalid. Reason: The receipt handle has expired.

似乎发生错误是因为我尝试在visibility timeout过期后删除邮件。我将默认可见性超时0更改为最大值,12小时,这部分解决了问题。有时可能会发生消息仍然在我的队列中超过12小时才能执行它而不是删除它,所以我将再次收到错误。是否有任何解决方案可以将可见性超时提高超过12小时或以其他方式绕过此错误?

4 个答案:

答案 0 :(得分:5)

TLDR :您想查看ChangeMessageVisibility API。

<强>详情

可见性超时的原因是确保处理消息的进程没有意外死亡,并允许消息由其他工作程序处理。

如果您的流程需要花费的时间超过配置的可见性超时,那么它本质上需要向SQS发送一些信号,上面写着“我还活着并正在处理此消息”。这就是ChangeMessageVisibility的用途。

如果消费和处理消息所需的时间差异很大,我建议设置一个小的默认可见性超时,并让工作人员发出“心跳”(使用ChangeMessageVisibility)来表示他们'仍然活着并致力于消息。这样,当工人合法地失败时,你仍然可以相对快速地恢复。

请注意,对于批量邮件,还有ChangeMessageVisibilityBatch

答案 1 :(得分:1)

尝试为要使用ReceiptHandle删除的消息增加sqs.receive_message()中的VisibilityTimeout参数的值

答案 2 :(得分:1)

将VisibilityTimeout:0更改为VisibilityTimeout:60可以正常工作

const params = {
        AttributeNames:[
            "SentTimestamp"
        ],
        MaxNumberOfMessages:10,
        MessageAttributeNames:[
            "All"
        ],
        QueueUrl:queueURL,
        VisibilityTimeout:60,
        WaitTimeSeconds:0,
    };
    sqs.receiveMessage(params,function (err,data) {
        console.log(data);
        if (err) {
            console.log("Receive Error", err);
        }else if (data.Messages) {
            let deleteParams = {
              QueueUrl: queueURL,
              ReceiptHandle: data.Messages[0].ReceiptHandle
            };
            sqs.deleteMessage(deleteParams, function(err, data) {
                  if (err) {
                    console.log("Delete Error", err);
                  } else {
                    console.log("Message Deleted", data);
                  }
            });
         }
    });

答案 3 :(得分:0)

将VisibilityTimeout设置为大于0即可工作