Amazon SQS消息消失了

时间:2019-05-23 08:40:00

标签: amazon-web-services boto3 amazon-sqs dead-letter

我有一个Amazon SQS队列和一个死信队列。

我的python程序从SQS队列获取一条消息,然后,如果引发异常,它将把该消息发送到死信队列。

现在,我有一个程序可以检查死信队列是否仍然可以处理这些消息。如果是,它将被发送回主SQS队列。您会看到,我在这里期望的是测试过程中的无限循环,但显然,经过2次尝试后消息消失了。为什么会这样?

当我在消息中放入一个多余的字段(它是随机值)时,它会以某种方式实现我所期望的(来回发送的无限循环)。 SQS中是否有一种机制可以阻止消息相同时我该怎么做?

def handle_retrieved_messages(self):
    if not self._messages:
        return None

    for message in self._messages:
        try:
            logger.info(
                "Processing Dead Letter message: {}".format(
                    message.get("Body")
                )
            )
            message_body = self._convert_json_to_dict(message.get("Body"))
            reprocessed = self._process_message(
                message_body, None, message_body
            )
        except Exception as e:
            logger.exception(
                "Failed to process the following SQS message:\n"
                "Message Body: {}\n"
                "Error: {}".format(message.get("Body", "<empty body>"), e)
            )
            # Send to error queue
            self._delete_message(message)
            self._sqs_sender.send_message(message_body)
        else:
            self._delete_message(message)
            if not reprocessed:
                # Send to error queue
                self._sqs_sender.send_message(message_body)

self._process_message将检查message_body是否将重处理标志设置为true。如果为true,则将其发送回主队列。

现在,我使消息的内容出现错误,因此每次在主队列中对其进行处理时,它将变为死信。然后我希望它保持循环运行,但是SQS似乎具有阻止这种情况发生的机制(这很好)。

问题是什么设置?

1 个答案:

答案 0 :(得分:2)

Amazon SQS队列的正常工作方式是:

  • 邮件已发送到队列
  • 应用程序在队列上调用ReceiveMessage()接收一条消息(或多条消息)。这会增加邮件的接收计数
  • 这会将邮件置于不可见状态。这意味着消息仍在队列中,但是如果另一个应用程序尝试从队列中接收消息,则看不到
  • 应用程序完成消息处理后,将调用DeleteMessage(),提供消息的消息句柄。这会从队列中删除邮件
  • 但是,如果应用程序 not 可见性超时期限内删除消息,则消息再次出现在队列中。如果应用程序崩溃,可以这样做。不会丢失消息,而是将其放回队列,以便另一个(或相同)应用程序可以再次处理它。
  • 如果邮件超过了可见性超时期限,并且其接收计数现在超过了最大接收次数设置,则将 not 放回队列。而是将其放置在死信队列(DLQ)中。

因此,正常过程是 Amazon SQS在收到的消息超过10次(在您的情况下)尝试将消息移动到DLQ 将消息移至“死信队列”不是应用程序的工作!

如果您想自己处理所有“死信”(例如移至不同的队列),请关闭队列本身的DLQ功能。这可能导致您的邮件消失或移至错误的位置。

在删除邮件时,您需要提供邮件的MessageHandle,而不是邮件本身。