首页 文章

如果我删除另一个消费者收到的SQS消息会怎样?

提问于
浏览
0

我有一个消费者,我怀疑它比默认的消息可见性花费更长的时间来处理给定的消息,但最终成功了 .

  • 如果 Consumer A 获得收据 R1M1 的消息 M1

  • 然后过了可见性超时

  • 然后 Consumer B 获取收据 R2M1 以获取消息 M1

  • 然后 Consumer A 调用 deleteMessage(R1M1)

邮件是删除的,还是留在队列中,因为另一个邮件的邮件收据更有效?

我观察到队列中的许多更复杂的消息有很多(50-1000)个收据,但我没有记录任何处理消息的失败 . 我怀疑我多次成功处理每条消息,然后删除操作无声地失败 .

1 回答

  • 1

    API Reference doumentation实际上与此相矛盾on the same page .

    DeleteMessage从指定的队列中删除指定的消息 . 您可以使用邮件的收据句柄而不是发送邮件时收到的MessageId来指定邮件 . 即使消息由于可见性超时设置而被其他阅读器锁定,它仍然会从队列中删除 .

    这看起来很简单,直到你继续阅读 .

    注意收据句柄与接收邮件的特定实例相关联 . 如果您不止一次收到邮件,则每次收到邮件时收到的收据句柄都不同 . 如果在使用DeleteMessage操作时未提供最近收到的邮件收据句柄,则请求会成功,但邮件可能不会被删除 .

    所以,你的问题的答案是“是的,绝对的,除了不,不一定 . ”

    但它确实解释了为什么你会有无声的失败 - 如果请求有效,删除显然不会失败 .

    这可能是SQS分布式特性的基本工件 - 如果传递消息的SQS内的特定节点发生故障,则可能会丢失较旧的消息收据 . 当然,我在猜测 .

    但是,从根本上说,如果遇到这种情况,你似乎确实存在设计缺陷 . 您要么发送后续请求以增加可见性超时,要么将默认可见性超时设置得足够高,以至于在正常情况下永远不会发生 . 最大值为12小时,对于大多数用例而言,这是很长的时间 .

    此外,您的消费者需要一种方法来验证消息是否已被操作 .

    将可见性超时视为重试计时器 .

    我的基础架构中的一个示例是一个系统,它对在S3中放入临时暂存存储桶的文件作出反应 . 队列使用者查找文件,并执行一些数据库查询以确定哪个或哪些系统可能需要该文件 . 然后,它将文件复制到目标系统桶,并且根据规则,它可以创建数据库条目和/或将消息发送到不同的队列以处理该文件 . 这种情况通常会在短短几秒内发生,如果一切顺利,消息将从队列中删除 . 如果出现问题,它只会忘记消息并返回轮询队列 .

    此队列的默认可见性超时设置为5分钟,这比过程通常需要的时间长得多,因为如果处理失败,我希望在多长时间内重试该消息 . 这就是你想要使用可见性超时的方式 .

    请注意,在标准处理条件下,正常模式过程永远不需要5分钟 .

    重试5次后,SQS将从主队列中删除该消息,并将该消息丢弃为死信队列(您可以选择该号码,我的设置为5) . 此队列由存储消息的单独进程使用,并提醒我此消息已超过其允许的接收数并且它从未被删除这一事实 - 指示毒丸消息或某种未处理的错误或慢性衰竭病情 .

相关问题