我有一个消费者,我怀疑它比默认的消息可见性花费更长的时间来处理给定的消息,但最终还是成功了。
Consumer A
收到消息R1M1
M1
Consumer B
收到消息R2M1
M1
Consumer A
来电deleteMessage(R1M1)
是删除的邮件,还是留在队列中,因为另一个邮件的邮件收据更有效?
我观察到我队列中的许多更复杂的消息有很多(50-1000)个收据,但我没有记录任何处理消息的失败。我怀疑我多次成功处理每条消息,然后删除操作无声地失败。
答案 0 :(得分:1)
API Reference doumentation实际上与此on the same page相矛盾。
<强> DeleteMessage可以强>
从指定的队列中删除指定的消息。您可以使用邮件的收据句柄指定邮件,而不是在发送邮件时收到的
MessageId
。即使消息由于可见性超时设置而被其他阅读器锁定,它仍然会从队列中删除。
这一点似乎很简单,直到你继续阅读。
注意强>
收据句柄与接收邮件的特定实例相关联。如果您不止一次收到邮件,则每次收到邮件时收到的收据句柄都不同。如果在使用
DeleteMessage
操作时未提供最近收到的邮件收据句柄,则请求会成功,但邮件可能不会被删除。
所以,你的问题的答案是“是的,绝对的,除了不,不一定。”
但它确实解释了为什么你会有无声的失败 - 如果请求有效,删除显然不会失败。
这可能是SQS分布式特性的基本工件 - 如果传送消息的SQS内的特定节点发生故障,可能会丢失较旧的消息收据。我当然在推测。
但是,从根本上说,如果遇到这种情况,你似乎确实存在设计缺陷。您要么发送后续请求以增加可见性超时,要么将默认可见性超时设置得足够高,以至于在正常情况下永远不会发生。最大值为12小时,对于大多数用例而言,这是很长的。
此外,您的消费者需要一种方法来验证消息是否已被采取行动。
将可见性超时视为重试计时器。
我的基础架构中的一个示例是一个系统,它对在S3中放入临时暂存存储桶的文件作出反应。队列使用者查找文件,并执行一些数据库查询以确定哪个或哪些系统可能需要该文件。然后,它将文件复制到目标系统桶,并且根据规则,它可以创建数据库条目和/或将消息发送到不同的队列以处理该文件。这种情况通常会在短短几秒内发生,如果一切顺利,消息将从队列中删除。如果出现问题,它只会忘记消息并返回轮询队列。
此队列的默认可见性超时设置为5分钟,这比过程通常需要的时间长得多,因为如果处理失败,我希望在多长时间内重试该消息。这就是你想要使用可见性超时的方法。
请注意,在标准处理条件下,正常模式过程永远不需要5分钟。
重试5次后,SQS会从主队列中删除该消息,然后将消息丢弃到死信队列中(您可以选择号码,我的设置为5)。此队列由存储消息的单独进程使用,并提醒我此消息已超过其允许的接收数并且它从未被删除 - 指示有毒药丸消息或某种未处理的错误或慢性衰竭病情。