Amazon SQS 死信队列 - Amazon Simple Queue Service
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 Amazon Web Services 服务入门

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

Amazon SQS 死信队列

Amazon SQS 支持死信队列(DLQ), 哪些其他队列 (源队列) 可将无法成功处理(使用)的消息作为目标。死信队列有助于调试您的应用程序或消息传递系统,因为它们可让您隔离未使用的消息以确定其处理失败的原因。有关使用 Amazon SQS 控制台创建队列并为其配置死信队列的信息,请参阅。配置死信队列(控制台). 调试消费者应用程序或使用者应用程序可用于使用消息后,可以使用死信队列重新驱动功能只需单击 Amazon SQS 控制台上的按钮即可将消息移回源队列。

重要

Amazon SQS 确实自动创建死信队列。您必须先创建队列,然后才能将其用作死信队列。

死信队列的工作方式

有时会因各种可能的问题 (例如,创建者应用程序或使用者应用程序内的错误条件或导致您的应用程序代码出现问题的意外状态更改) 而导致无法处理消息。例如,如果用户使用某特定产品 ID 下达 Web 订单,但产品 ID 已被删除,则 Web 商店的代码会失败并显示错误,而且包含订单请求的消息将发送到死信队列。

有时,创建器和使用器可能无法解释其用于通信的协议的各个方面,从而导致消息中断或丢失。此外,使用者的硬件错误可能会中断消息负载。

这些区域有:重新驱动策略指定源队列死信队列以及 Amazon SQS 将消息从前者移至后者的条件 (如果源队列的使用者无法处理消息指定次数)。这些区域有:maxReceiveCount是指在将消息移至死信队列之前,使用者尝试从队列接收消息而不将其删除的次数。设置maxReceiveCount如果值较低,如 1,将导致无法接收消息,从而导致消息移至死信队列。此类失败包括网络错误和客户端依赖性错误。为了确保您的系统能够抵御错误,请将maxReceiveCount足够高以允许足够的重试次数。

这些区域有:重新驱动允许策略指定哪些源队列可以访问死信队列。此策略适用于潜在的死信队列。您可以选择是允许所有源队列、允许特定的源队列还是拒绝所有源队列。默认情况下允许所有源队列使用死信队列。如果您选择允许特定队列(使用byQueue选项),您可以使用源队列 Amazon 资源名称 (ARN) 指定最多 10 个源队列。如果你指定denyAll中,队列无法用作死信队列。

要指定死信队列,您可以使用控制台或Amazon SDK for Java. 您必须为将消息发送到死信队列的每个队列执行此操作。同一类型的多个队列可将一个死信队列作为目标。有关更多信息,请参阅 。配置死信队列(控制台)RedrivePolicyRedriveAllowPolicy的属性CreateQueue要么SetQueueAttributesaction.

重要

FIFO 队列的死信队列也必须是 FIFO 队列。同样,标准队列的死信队列也必须是标准队列。

您必须使用相同的Amazon Web Services 账户以创建死信队列以及向死信队列发送消息的其他队列。此外,死信队列必须驻留在使用死信队列的其他队列所在的区域中。例如,如果在美国东部 (俄亥俄) 区域中创建一个队列,并且要对该队列使用死信队列,则第二个队列也必须位于美国东部 (俄亥俄) 区域中。

消息的过期时间始终基于其原始入队时间戳。将消息移至死信队列时,入队列的时间戳将保持不变。这些区域有:ApproximateAgeOfOldestMessage指标指示消息何时移动到死信队列,最初发送消息的时间。例如,假设消息在原始队列中花费 1 天时间,然后才移动到死信队列。如果死信队列的保留期为 4 天,则该消息将在 3 天后从死信队列中删除,ApproximateAgeOfOldestMessage是 3 天。因此,最佳做法是始终将死信队列的保留期限设置为长于原始队列的保留期。

死信队列有哪些好处?

死信队列的主要任务是处理未使用的消息的生命周期。死信队列可让您留出并隔离无法正确处理的消息以确定其处理失败的原因。设置死信队列可让您执行以下操作:

  • 为移动到死信队列的任何消息配置警报。

  • 检查日志以了解可能导致消息移至死信队列的异常。

  • 分析移动到死信队列的消息的内容以诊断软件或生产者或消费者的硬件问题。

  • 确定是否为使用者提供了充足的时间来处理消息。

不同的队列类型如何处理消息失败?

标准队列

标准队列保留期结束前继续处理消息。这种连续处理消息最大程度地减小队列由无法处理的消息阻止的几率。连续消息处理还可以更快地恢复您的队列。

在一个处理数千条消息的系统中,拥有使用器反复无法确认和删除的大量消息可能会增加成本并给硬件带来额外负载。最好是在几次处理尝试之后将失败的消息移至死信队列,而不是在这些消息到期前一直尝试处理它们。

注意

标准队列允许大量正在传输的消息。如果大多数消息无法使用且没有发送到死信队列,则处理有效消息的速率将下降。因此,要保持队列的效率,请确保您的应用程序正确处理消息。

FIFO 队列

FIFO 队列通过按顺序使用消息组中的消息,只进行一次处理。因此,尽管使用者可继续检索另一个消息组中的有序消息,但在阻止队列的消息得到成功处理之前,第一个消息组将保持不可用状态。

注意

FIFO 队列允许少量正在传输的消息。因此,为了防止 FIFO 队列被消息阻止,请确保您的应用程序正确处理消息处理。

何时应使用死信队列?

请不要对标准队列使用死信队列。如果您的应用程序不依赖订购,您应始终利用死信队列。死信队列可帮助您排查不正确的消息传输操作的问题。

注意

即使您使用死信队列,也应继续监控您的队列并重试发送因临时原因而失败的消息。

请不要使用死信队列来减少消息量并降低将系统公开给其中的几率。毒丸消息(可以接收但无法处理的消息)。

如果要无限地重试传输消息,请不要对标准队列使用死信队列。例如,如果您的程序必须等待相关进程变得活动或可用,请不要使用死信队列。

如果您不想中断消息或操作的准确顺序,请不要对 FIFO 队列使用死信队列。例如,请不要对视频编辑套件的编辑决策列表 (EDL) 中的指令使用死信队列,此情况下,更改编辑的顺序将更改后续编辑的上下文。

将消息移出死信队列

您可以使用重新驱动死信队列以管理未使用消息的生命周期。在调查死信队列中标准未使用消息的属性和相关元数据之后,您可以将这些消息重新驱动回其源队列。死信队列重新驱动通过在移动消息时批处理消息来减少 API 调用计费。

重新驱动任务使用 Amazon SQSSendMessageBatchReceiveMessage, 和DeleteMessageBatch代表用户重新驱动消息的 API。因此,所有重新驱动的消息都被视为带有新消息的新消息messageidenqueueTime以及保留期。死信队列重新驱动的定价使用调用的 API 调用数量和基于Amazon SQS 定价.

默认情况下,死信队列重新驱动将消息从死信队列移动到源队列。但是,您也可以将任何其他标准队列配置为重新驱动目标。此外,您可以配置重新驱动速度以设置 Amazon SQS 移动消息的速率。有关使用 Amazon SQS 控制台配置死信队列重新驱动的说明,请参阅配置死信队列重驱(控制台).

注意

Amazon SQS 控制台中仅为标准队列支持死信队列重新驱动。

Amazon SQS 不支持在从死信队列中重新驱动消息时过滤和修改消息。

死信队列重新驱动任务最多可以运行 36 小时。Amazon SQS 支持每个账户最多 100 个活动的重新驱动任务。

排查死信队列的问题

在某些情况下,Amazon SQS 死信队列的行为可能并不总是符合预期。此部分概述了常见问题并说明如何解决这些问题。

使用控制台查看消息可能会导致消息移至死信队列

Amazon SQS 将根据相应队列的重新驱动策略在控制台中查看消息的计数。因此,如果在控制台中查看消息(按相应队列的重新驱动策略中指定的次数),则该消息将移至相应队列的死信队列中。

要调整此行为,您可以执行下列操作之一:

  • 针对相应队列的重新驱动策略增大 Maximum Receives 设置。

  • 避免在控制台中查看相应队列的消息。

死信队列的 NumberOfMessagesSentNumberOfMessagesReceived 不匹配

如果您手动向死信队列发送消息,它将由 NumberOfMessagesSent 指标捕获。不过,如果因处理尝试失败而发送消息到死信队列,则此指标不会捕获该消息。因此,NumberOfMessagesSentNumberOfMessagesReceived 的值可能不同。

有关使用 Amazon SQS 控制台创建和配置死信队列重新驱动的信息。

请注意,死信队列重新驱动要求您为 Amazon SQS 设置适当的权限以接收死信队列的消息并将消息发送到目标队列。如果权限不足,死信队列重新驱动到源队列不会启动消息重新驱动,并且可能会失败任务。您可以查看消息重新驱动任务的状态以修复问题并重试。