Amazon SQS支持死信队列(DLQ),其他队列(源队列)可以针对无法成功处理(消耗)的消息。死信队列对于调试您的应用程序或消息传递系统非常有用,因为它们可以让您隔离未消耗的消息,以确定为什么它们的处理没有成功。关于创建队列和使用Amazon SQS控制台为其配置死信队列的信息,请参阅配置死信队列(控制台)。一旦你调试了消费者应用程序或消费者应用程序可以消费消息,你可以使用死信队列重新驱动的功能,只需在Amazon SQS控制台点击一个按钮就可以将消息移回源队列。
死信队列的工作方法
有时,消息不能被处理是因为各种可能的问题,如生产者或消费者应用程序内的错误条件,或意外的状态变化导致你的应用程序代码出现问题。例如,如果一个用户用一个特定的产品ID下了一个网络订单,但这个产品ID被删除了,网络商店的代码就会失败并显示一个错误,带有订单请求的消息就会被发送到一个死信队列中。
偶尔,生产者和消费者可能无法解释他们用于通信的协议的某些方面,导致消息损坏或丢失。另外,消费者的硬件错误可能会损坏消息的有效载荷。
重新驱动策略指定了源队列、死信队列,以及在源队列的消费者未能处理一个消息达到指定次数时,Amazon SQS将消息从前者移到后者的条件。maxReceiveCount是消费者在被转移到死信队列之前尝试从队列中接收消息而不删除的次数。将maxReceiveCount设置为一个低值,如1,将导致任何接收消息的失败,导致消息被移到死信队列。这样的失败包括网络错误和客户端依赖性错误。为了确保你的系统对错误有弹性,把maxReceiveCount设置得足够高,以允许足够的重试。
重新驱动允许策略指定了哪些源队列可以访问死信队列。这个策略适用于一个潜在的死信队列。你可以选择是允许所有源队列,允许特定的源队列,还是拒绝所有源队列。默认是允许所有源队列使用死信队列。如果你选择允许特定队列(使用byQueue选项),你可以使用源队列亚马逊资源名称(ARN)指定多达10个源队列。如果你指定denyAll,该队列不能作为死字队列使用。
要指定一个死字队列,你可以使用控制台或AWS SDK for Java。你必须为每个向死字队列发送消息的队列这样做。同一类型的多个队列可以针对一个死字母队列。更多信息,请参阅配置死信队列(控制台)以及 CreateQueue 或 SetQueueAttributes 操作的 RedrivePolicy 和 RedriveAllowPolicy 属性。
死信队列的好处
死信队列的主要任务是处理未消耗的消息的生命周期。死信队列可以让你把不能正确处理的消息放在一边,并将其隔离,以确定为什么它们的处理没有成功。设置一个死信队列可以让你做以下事情。
为任何转移到死信队列的邮件配置一个警报。
检查日志,看是否有可能导致邮件被移到死信队列的异常。
分析移动到死信队列的消息内容,以诊断软件或生产者或消费者的硬件问题。
确定你是否给了消费者足够的时间来处理消息。
不同的队列类型如何处理消息失败
标准队列
标准队列持续处理消息,直到保留期到期。这种对消息的连续处理使你的队列被无法处理的消息阻塞的几率降到最低。连续的消息处理也为你的队列提供更快的恢复。
在一个处理成千上万条消息的系统中,如果有大量的消息被消费者反复确认和删除,可能会增加成本并给硬件带来额外的负荷。与其试图处理失败的消息直到它们过期,不如在几次处理尝试后将它们移到死信队列中。
FIFO队列
FIFO队列通过从一个消息组中依次消费消息来提供完全的一次处理。因此,尽管消费者可以继续从另一个消息组检索有序的消息,但第一个消息组仍然不可用,直到阻塞队列的消息被成功处理。