处理后从 SQS 队列中删除消息

Deleting messages from SQS queue after processing

我的应用程序将消息发送到 AWS SQS 队列以获取需要某种后台处理的作业。我的处理守护进程接收并处理这样的消息:

$result = $sqsClient->receiveMessage([
    'QueueUrl' => \Myapp\Config::get('sqs.queue'),
    'WaitTimeSeconds' => 20,
    'MaxNumberOfMessages' => 1
]);

if (isset($result['Messages'])) {
    foreach ($result->getPath('Messages/*/Body') as $messageBody) {
        $handler = new \Myapp\Handler();
        $handler->dispatch($messageBody);
    }
}

这工作正常,但是我可以从 SQS 控制台看到我的脚本检索的消息被放入 "Messages in Flight" 类别,然后过一会儿它们又被放回 "Messages Available",我的脚本最终再次拾起它们。

如何从 SQS 队列中删除消息,或者更好地将它们标记为已完成?

当您收到来自 SQS 队列的消息时,该消息(默认情况下)将在 30 秒后 return 到队列。这是为了处理消息处理崩溃,需要重新处理消息的情况。

成功处理您的消息后,使用deleteMessage删除消息。当您从 receiveMessage 收到消息时,您需要消息中的 receiptHandle 值才能删除消息。

如果您的邮件的典型处理时间可能超过 30 秒,那么您可以配置队列以增加 "return to queue" 时间。这在 SQS 队列配置中称为 "Default Visibility Timeout"。

另请注意,Amazon SQS 的工作方式如下:

  1. 与消息添加到队列的方式相比,消息可能会乱序接收
  2. 消息可能会收到两次,因此请允许您的消息处理器处理这些情况

您确实需要在处理完邮件后将其删除 - 这将被视为 'marking them completed';但是,如果下游需要对这个 'completed'' 操作采取行动,我通常会 post 向另一个 SQS 队列发送 'completion' 消息,然后从传入队列中删除该消息.通过这种方式,另一个进程,无论是现在还是未来,都可以在第一个工作人员完成其工作时采取需要完成的操作,即以解耦的方式将这些进程链接在一起。

如果下游没有什么需要做的,直接删除即可。