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

doe*_*oej 2 queue amazon-sqs amazon-web-services

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

Value {VALUE} for parameter ReceiptHandle is invalid. Reason: The receipt handle has expired.
Run Code Online (Sandbox Code Playgroud)

似乎发生错误是因为我试图在visibility timeout过期后删除该消息。我将默认可见性超时0更改为最大12小时,这部分解决了问题。有时可能会发生,一条消息仍在我的队列中超过12个小时,然后我才能执行并删除该消息,因此我将再次收到错误消息。有什么解决方案可以将可见性超时增加12小时以上,或通过其他方式绕过此错误?

Che*_*ger 49

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

轮询停止时出现错误 轮询停止时出现错误

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

轮询时,选择消息并删除
在轮询过程中,选择并删除

消息删除成功。 消息删除成功。


小智 8

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

  • 谢谢大佬,就是这样。我以为 VisibilityTimeout 仅在队列本身上设置,但事实证明 boto3 调用上的 VisibilityTimeout 会覆盖它并使消息不可删除。按照您的建议进行更改解决了问题 (2认同)

Kre*_*ase 5

TLDR:您想研究ChangeMessageVisibilityAPI。

细节

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

如果您的过程需要比配置的可见性超时更长的时间,则本质上它需要向SQS发送一些信号,指出“我还活着,并且正在处理此消息”。那ChangeMessageVisibility是为了什么

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

请注意,也ChangeMessageVisibilityBatch可以对成批的消息执行此操作。

  • 请注意,如果您已将最大值设置为 12 小时,则延长时间不能超过 12 小时。 (2认同)