API 参考文档实际上自相矛盾on the same page 关于这一点。
删除消息
从指定队列中删除指定消息。您可以使用消息的接收句柄来指定消息,而不是使用发送消息时收到的 MessageId。
即使消息由于可见性超时设置而被另一个阅读器锁定,它仍然会从队列中删除。
这似乎很简单,直到您继续阅读。
注意
接收句柄与接收消息的特定实例相关联。如果您多次收到一条消息,那么您每次收到该消息时得到的回执句柄是不同的。如果您在使用DeleteMessage 操作时未提供消息的最新接收句柄,则请求成功,但消息可能不会被删除。
因此,您的问题的答案是“是的,绝对是,但不是,不一定。”
但它确实解释了为什么会出现静默失败——如果请求有效,删除显然不会失败。
这可能是 SQS 分布式特性的一个基本产物——如果 SQS 内传递消息的特定节点发生故障,则可能是旧的消息回执可能会丢失。当然,我是在猜测。
不过,从根本上说,如果您遇到这种情况,您似乎确实存在设计缺陷。您要么发送后续请求以增加可见性超时,要么将默认可见性超时设置得足够高,使其在正常情况下永远不会发生。最大值为 12 小时,这对于大多数用例来说太长了。
此外,您的消费者需要一种方法来验证消息是否已被执行。
将可见性超时视为重试计时器。
我的基础架构中的一个示例是一个系统,它对被放入 S3 中的临时暂存桶的文件做出反应。队列使用者查找该文件,并执行一些数据库查询以确定哪个或哪些系统可能需要该文件。然后它将文件复制到目标系统存储桶,并且根据规则,它可以创建数据库条目和/或将消息发送到不同的队列以处理该文件。这通常会在短短几秒钟内发生,如果一切顺利,消息就会从队列中删除。如果出现问题,它就会忘记消息并返回轮询队列。
此队列的默认可见性超时设置为 5 分钟,这比该过程通常需要的时间长得多,因为这是我希望在处理失败时重试消息的时间。这就是您想要使用可见性超时的方式。
请注意,在标准处理条件下,正常模式处理永远不需要 5 分钟。
重试 5 次后,SQS 将消息从主队列中移除,并将消息丢弃到死信队列中(您可以选择数字,我的设置是 5)。此队列由存储消息的单独进程使用,并提醒我该消息已超过其允许的接收次数并且从未被删除 - 指示毒丸消息或某种未处理的错误或慢性衰竭状态。