本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
Amazon SQS 死信队列
Amazon SQS 支持死信队列(DLQ),哪些其他队列 (源队列) 可将其作为无法成功处理(使用)的消息的目标。死信队列有助于调试您的应用程序或消息传递系统,因为它们可让您隔离未使用的消息以确定其处理失败的原因。有关使用 Amazon SQS 控制台创建队列并为其配置死信队列的信息,请参阅配置死信队列(控制台). 调试使用者应用程序或使用者应用程序可用于消费消息后,您可以使用死信队列重新驱动功能只需在 Amazon SQS 控制台上单击一个按钮,即可将消息移回源队列。
Amazon SQS 确实如此不自动创建死信队列。必须先创建队列才能将其用作死信队列。
死信队列的工作方式
有时会因各种可能的问题 (例如,创建者应用程序或使用者应用程序内的错误条件或导致您的应用程序代码出现问题的意外状态更改) 而导致无法处理消息。例如,如果用户使用某特定产品 ID 下达 Web 订单,但产品 ID 已被删除,则 Web 商店的代码会失败并显示错误,而且包含订单请求的消息将发送到死信队列。
有时,创建器和使用器可能无法解释其用于通信的协议的各个方面,从而导致消息中断或丢失。此外,使用者的硬件错误可能会中断消息负载。
这些区域有:重新驱动政策指定源队列,那个死信队列以及 Amazon SQS 将消息从前者移至后者的条件 (如果源队列的使用者无法处理消息指定次数)。这些区域有:maxReceiveCount是使用者在发送到死信队列之前尝试从队列接收消息而不删除消息的次数。设置的maxReceiveCount设置为较低的值(如 1)将导致无法接收消息,从而导致消息被移至死信队列。此类故障包括网络错误和客户端依赖关系错误。要确保您的系统能够抵御错误,请将maxReceiveCount足够高,足以允许足够的重试。
这些区域有:重启允许策略指定哪些源队列可访问死信队列的源队列。此策略适用于潜在的死信队列。您可以选择是允许所有源队列、允许特定源队列还是拒绝所有源队列。默认设置是允许所有源队列使用死信队列。如果您选择允许特定的队列(使用byQueue选项),则可以使用源队列亚马逊资源名称 (ARN) 指定最多 10 个源队列。如果你指定denyAll,则该队列不能用作死信队列。
要指定死信队列,您可以使用控制台或Amazon SDK for Java. 您必须为将消息发送到死信队列的每个队列执行此操作。同一类型的多个队列可将一个死信队列作为目标。有关更多信息,请参阅 。配置死信队列(控制台)和RedrivePolicy和RedriveAllowPolicy的属性CreateQueue要么SetQueueAttributesaction.
FIFO 队列的死信队列也必须是 FIFO 队列。同样,标准队列的死信队列也必须是标准队列。
您必须使用相同的Amazon Web Services 账户创建死信队列以及向死信队列发送消息的其他队列。此外,死信队列必须驻留在使用死信队列的其他队列所在的区域中。例如,如果您在美国东部 (俄亥俄) 区域创建队列并且要对该队列使用死信队列,则第二个队列也必须位于美国东部 (俄亥俄) 区域中。
消息的到期时间始终基于其原始入队时间戳。当消息移至死信队列时,入队时间戳将保持不变。这些区域有:ApproximateAgeOfOldestMessagemetric 指示消息何时移至死信队列,不消息最初发送的时间。例如,假设消息在移动到死信队列之前在原始队列中停留了 1 天。如果死信队列的保留期为 4 天,则该消息将在 3 天后从死信队列中删除,并且ApproximateAgeOfOldestMessage是 3 天。因此,最佳做法是始终将死信队列的保留期设置为比原始队列的保留期长。
死信队列有哪些好处?
死信队列的主要任务是处理未使用消息的生命周期。利用死信队列,您可以留出和隔离无法正确处理的消息以确定其处理失败的原因。设置死信队列可让您执行以下操作:
-
为移动到死信队列的任何消息配置警报。
-
查看日志以了解可能导致消息移至死信队列的异常。
-
分析移动到死信队列的消息的内容,以诊断软件问题或创建者/使用者的硬件问题。
-
确定是否为使用者提供了充足的时间来处理消息。
不同的队列类型如何处理消息失败?
标准队列
标准队列继续处理消息,直到保留期结束为止。这种持续处理消息的能力可最大程度地减小队列由无法处理的消息阻止的几率。连续消息处理还可以加快队列的恢复速度。
在一个处理数千条消息的系统中,拥有使用器反复无法确认和删除的大量消息可能会增加成本并给硬件带来额外负载。最好是在几次处理尝试之后将失败的消息移至死信队列,而不是在这些消息到期前一直尝试处理它们。
标准队列允许大量正在传输的消息。如果您的大多数消息无法使用且无法发送到死信队列,则处理有效消息的速率将下降。因此,要保持队列的效率,请确保应用程序正确处理消息。
FIFO 队列
FIFO 队列通过按顺序使用消息组中的消息,提供只进行一次处理。因此,尽管使用者可继续检索另一个消息组中的有序消息,但在阻止队列的消息得到成功处理之前,第一个消息组将保持不可用状态。
FIFO 队列允许少量正在传输的消息。因此,为了防止您的 FIFO 队列被消息阻塞,请确保您的应用程序正确处理消息。
何时应使用死信队列?
请将死信队列用于标准队列中。当您的应用程序不依赖排序时,您应始终利用死信队列。死信队列可帮助您排查不正确的消息传输操作的问题。
即使您使用死信队列,也应继续监控您的队列并重试发送因临时原因而失败的消息。
请不要使用死信队列来减少消息数和降低将系统公开给您的系统的几率毒丸消息(可以接收但无法处理的消息)。
如果需要无限地重试传输消息,请不要对标准队列使用死信队列。例如,如果您的程序必须等待某个依赖过程变得有效或可用,请不要使用死信队列。
如果不想中断消息或操作的准确顺序,请不要对FIFO队列使用死信队列。例如,请不要对视频编辑套件的编辑决策列表 (EDL) 中的指令使用死信队列,此情况下,更改编辑的顺序将更改后续编辑的上下文。
将消息移出死信队列
您可以使用重新驱动死信队列的问题管理未消费消息的生命周期。在调查了死信队列中适用于标准未消费消息的属性和相关元数据之后,您可以将这些消息重新驱动回其源队列。死信队列重新驱动通过在移动消息的同时对消息进行批处理,从而减少了 API 调用计费。
重新驱动任务使用亚马逊 SQSSendMessageBatch、ReceiveMessage, 和DeleteMessageBatch代表用户重新驱动消息的 API。因此,所有重新驱动的消息都被视为带有新消息的新消息messageid、enqueueTime和保留期。死信队列重新驱动的定价使用调用的 API 调用次数和账单基于Amazon SQS 定价
默认情况下,死信队列重新驱动会将消息从死信队列移动到源队列。但是,您也可以将任何其他标准队列配置为重新驱动目标。此外,您还可以配置重新驱动速度来设置 Amazon SQS 移动消息的速率。有关使用 Amazon SQS 控制台配置死信队列重新驱动的说明,请参阅配置死信队列重新驱动程序(控制台).
Amazon SQS 仅支持Amazon SQS 控制台中的标准队列重新驱动死信队列。
Amazon SQS 不支持在从死信队列中恢复消息时筛选和修改消息。
死信队列重新驱动任务最多可以运行 36 个小时。Amazon SQS 支持每个账户最多 100 个活动的重新驱动任务。
排查死信队列的问题
在某些情况下,Amazon SQS 死信队列的行为可能并不总是符合预期。此部分概述了常见问题并说明如何解决这些问题。
使用控制台查看消息可能会导致消息移至死信队列
Amazon SQS 在控制台中根据相应队列的重新驱动策略查看消息时,将进行计数。因此,如果在控制台中查看消息相应队列的重新驱动策略中指定的次数,则该消息将会移至相应队列的死信队列中。
要调整此行为,您可以执行下列操作之一:
-
针对相应队列的重新驱动策略增大 Maximum Receives 设置。
-
避免在控制台中查看相应队列的消息。
死信队列的 NumberOfMessagesSent 和 NumberOfMessagesReceived 不匹配
如果您手动向死信队列发送消息,它将由 NumberOfMessagesSent 指标捕获。不过,如果因处理尝试失败而发送消息到死信队列,则此指标不会捕获该消息。因此,NumberOfMessagesSent 和 NumberOfMessagesReceived 的值可能不同。
有关使用 Amazon SQS 控制台创建和配置死信队列重新驱动的信息
请注意,重新驱动死信队列需要您为 Amazon SQS 设置适当的权限,以接收死信队列中的消息以及向目标队列发送消息。如果权限不足,死信队列重新驱动到源队列不会启动消息重新驱动,并且可能会使任务失败。您可以查看消息重新驱动任务的状态以修复问题并重试。