AWS SQS-在一条消息的可见性超时到期之前,队列不传递任何消息

zen*_*con 2 go amazon-sqs

编辑在我撰写本文时解决了这个问题:P-我喜欢这种解决方案。我认为无论如何我都会张贴它,也许其他人也会遇到同样的问题并找到我的解决方案。不在乎积分/因果关系等。我已经把整个事情写完了,所以我想把它和解决方案贴出来。

我有一个SQS FIFO队列。它正在使用一个死信队列。这是它的配置方式:

FIFO队列配置

我有一个生产者微服务,并且有10个ECS映像作为使用者运行。

重要的是,出于业务原因,我们必须在队列中传递消息的时间附近处理消息。

我们正在使用同时适用于生产者代码和使用者代码的AWS SDK Golang客户端软件包的最新版本(如果重要,我可以查找该版本,但并不是很过时)。

我捕获了生产者的日志,因此我确切地知道何时将消息放入队列中以及消息是什么。

我捕获所有使用者的汇总日志,因此我可以全面了解所有10个使用者以及何时接收和处理消息。

这是正常情况下查看日志的结果:

  1. 消息在时间x放入队列
  2. 时间x的十个消费者之一收到的消息
  3. 消费者成功处理了消息
  4. 使用者在时间x +(0-2秒)从队列中删除了消息
  5. 每天在不同的时间重复无限广告,每天最多重复约700条消息

但是我现在看到的问题是某些消息没有得到及时处理。有时,我们故意针对该消息处理系统状态的消息失败(例如,用户仍在登录,因此它应该退回并重试...)。问题是,如果使用者失败了一条消息,则会导致队列停止将任何其他消息传递给任何其他使用者。

这里的“无法处理消息”仅表示已接收到消息,但使用者将其声明为失败,因此我们只记录一个错误,而不继续从队列中删除它。因此,可见性超时(此处为5m)将过期,并将其重新交付给另一个使用者并重试10次,之后它将进入死信队列。

在深入研究日志并进行分析之后,这就是我所看到的:

  1. 流程如上所述开始(产生,消费,删除的消息)。
  2. 消费者在时间x收到新消息
  3. 使用者失败-记录错误并仅返回(不删除)
  4. 在x + 5m(可见性超时)时间再次收到相同的消息
  5. 使用者失败-记录错误并仅返回(不删除)
  6. 重复最多10次-消息进入死信队列
  7. 收到新消息,但现在晚了50分钟!
  8. 现在,在第2步到第7步之间放入队列的所有邮件都晚了50分钟(5m可见性超时* 10次重试)

所有我读过的文档告诉我的队列应该没有这样的行为,但我已经验证了它几次在我们的日志。遗憾的是,我们没有付费的AWS支持计划,或者我要向他们提交罚单。但是,请考虑以下事实:我们有10个独立的使用者都在同一队列中进行读取。他们仅从此队列读取。我们没有正在使用的任何其他队列。

对于重复数据删除,我们使用消息正文的自动哈希。消息是小的JSON文档。

我的期望是,如果我们有一条不良消息导致可见性超时,那么在有可用使用者的情况下,队列仍会愉快地传递其可用的任何其他消息。

zen*_*con 6

好的,原来我错过了文档中有关FIFO队列的一点信息:

https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/FIFO-queues.html

在此处输入图片说明

当您收到带有消息组ID的消息时,除非您删除该消息或该消息变得可见,否则不会再返回相同消息组ID的消息。

我确实使用了相同的消息组ID。没有再考虑。请注意,如果您这样做,并且任何一条消息都无法处理,它将备份队列中的所有其他消息,直到最终处理完该消息为止。对我来说,解决方案是更改消息组ID。我可以在其中添加一些可用于我的业务逻辑ID。

  • *“当有可用的消费者时,队列仍然会很高兴地传递它可用的任何其他消息。”* 那么它就不会是“FIFO”。这就是这种行为的原因——因此具有相同 message-group-id 的消息不会被无序传递。 (2认同)