具有 DLQ 的 SQS - 消息处理

SQS with DLQ - Message processing

我对 SQS Source Queue 及其 DLQ 如何处理消息有疑问。

我知道 SQS 没有像 JMS 那样实现事务处理,而是使用带超时的锁,以便其他订阅者可以在超时到期后从队列中拉取它。

话虽如此,我怎样才能实现下面的行为(使用更多的 SQS 配置而不是客户端实现)?

这基本上是为您内置在 SQS 中的。通常,您的配置会将死信队列作为主队列的重新驱动目标。指定 3 作为重新驱动策略的 "Maximum Receives"。然后,您的主要代码将类似于:

while( true ) {
    ReceiveMessageRequest receiveMessageRequest =
          new ReceiveMessageRequest(eventQueueUrl)
                        .withMaxNumberOfMessages(10)
                        .withWaitTimeSeconds(5);

    List<Message> messages = amazonSQS.receiveMessage(receiveMessageRequest)
                                                              .getMessages();

   for (Message nextMessage: messages) {
       // handle the message.  if the handling fails just continue.

       // if the message was processed correctly, delete it
       amazonSQS.deleteMessage(queueURL,nextMessage.getReceiptHandle() );
   }
}

这里的关键是,如果您不从主队列中删除邮件,默认情况下,它会在 30 秒后再次可用。这可以作为主队列 "Default Visibility Timeout" 的一部分进行更改。如果您确实删除了它,那么它将永远不会再出现。在您的失败场景中,您将处理消息 3 次,在失败多次后,它将自动移至死信队列。

关于死信队列的一个小警告 - 在您尝试第 第四次 阅读消息之前,消息不会被移动到死信队列。您的代码将永远看不到它,但如果您尝试 3 次并期望它在第三次读取后最终出现在 DLQ 中,您将看不到它。当您第 4 次尝试阅读它时,AWS 意识到它不能给您并为您移动它。

顺便说一句 - 我假设 Java 鉴于你提到了 JMS。