【问题标题】:Deleting message from SQS FIFO queue: The receipt handle has expired从 SQS FIFO 队列中删除消息:接收句柄已过期
【发布时间】:2023-03-03 08:48:23
【问题描述】:

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

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

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

【问题讨论】:

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


    【解决方案1】:

    TLDR:您想查看ChangeMessageVisibility API。

    详情

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

    如果您的进程需要比配置的可见性超时更长的时间,它本质上需要向 SQS 发送一些信号,表明“我还活着并正在处理此消息”。这就是ChangeMessageVisibility 的用途。

    如果您在使用和处理消息所需的时间方面存在很大差异,我建议设置一个较小的默认可见性超时并让您的工作人员发出“心跳”(使用ChangeMessageVisibility)以表明他们仍在活着并且正在处理消息。这样,当工作人员合法地失败时,您仍然可以相对较快地恢复。

    请注意,还有ChangeMessageVisibilityBatch 用于批量处理消息。

    【讨论】:

    • 请注意,如果您已将最大值设置为 12 小时,则不能超过 12 小时。
    【解决方案2】:

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

    【讨论】:

    • 谢谢老兄,就是这样。我认为 VisibilityTimeout 仅在队列本身上设置,但结果证明 boto3 调用上的 VisibilityTimeout 会覆盖它并使消息不可删除。按照您的建议更改它解决了问题
    【解决方案3】:

    您可以在 AWS 控制台中执行此操作,但诀窍是,您必须在轮询进度仍处于活动状态时执行此操作。
    例如,当您轮询 10 秒时,有 10 条消息,您需要在 10 秒内或在第 10 条消息到达之前删除该消息,以先到者为准,在轮询停止后,您的删除窗口关闭。

    轮询停止时出现错误

    调整轮询持续时间和消息数

    轮询时,选择消息并删除

    消息已成功删除。

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        【解决方案5】:

        将 VisibilityTimeout 设置为大于 0 将起作用

        【讨论】:

          猜你喜欢
          • 2022-09-23
          • 2018-12-31
          • 1970-01-01
          • 2019-11-07
          • 1970-01-01
          • 2013-10-17
          • 2015-04-23
          • 2020-03-24
          • 2018-08-29
          相关资源
          最近更新 更多