Amazon SQS 死信队列:真的是死信还是毒药?

Posted

技术标签:

【中文标题】Amazon SQS 死信队列:真的是死信还是毒药?【英文标题】:Amazon SQS Dead Letter Queue: Is it really dead letter or poison? 【发布时间】:2014-03-14 06:17:38 【问题描述】:

我正试图澄清亚马逊的 SQS 死信队列到底在做什么。

根据http://aws.typepad.com/aws/2014/01/amazon-sqs-new-dead-letter-queue.html

Dead Letter Queue - SQS 队列的 ARN(Amazon 资源名称),将接收在消费者 receives 达到最大次数后未成功处理的消息。

这听起来不是更像毒药队列吗?关键区别在于消费者确实收到了消息。死信是指消息可能很好,但可能由于服务中断而无法传递。 http://www.eaipatterns.com/DeadLetterChannel.html

这听起来像是多次成功接收到消息,但处理消息失败,我理解这是毒消息队列的含义。

消息总线与队列

死信模式在普通旧队列的上下文中是否具有不同的含义?由于 SQS 只是一个队列,而不是消息总线,因此它不负责传递消息。相反,它等待消息被拾取(请求)。所以传统的死信模式并不真正适用,因为没有消息总线试图传递消息并且无法找到接收者。

SQS 可以像消息总线一样工作吗?

有没有办法通过 SQS 设置通道和侦听器,而不是显式轮询队列中的消息?

【问题讨论】:

这是一个支持工具。问:我的消息到底发生了什么? A:哦,它在死信队列中。 看起来他们的实现有些欠缺。所有这些都是对代码中糟糕的断言/输入检查的后备。我认为您可能希望对不良消息的处理方式更加谨慎。 【参考方案1】:

好问题。

基于您引用的 the canonical source 的定义(为清楚起见,已删除引用):

死信通道的具体工作方式取决于特定消息传递系统的实现(如果它提供的话)。该通道可以称为“死消息队列”或“死信队列”。通常,安装了消息传递系统的每台机器都有自己的本地死信通道,因此无论消息死在什么机器上,它都可以从一个本地队列移动到另一个本地队列,而没有任何网络不确定性。这也记录了消息死在哪台机器上。当消息传递系统移动消息时,它还可能记录消息应该传递的原始通道。

...不清楚是否真的有区别。我理解您所说的“毒药队列”是什么意思,并且您对 SQS 的工作原理的理解是正确的。从语义上讲,DLQ 和 PQ 之间的区别——电子邮件风格中的“无法投递”与“毒药”——我并不清楚。也许 PQ 是 DLQ 的一种。

FWIW,ActiveMQ's redelivery policy 使用与 SQS 相同的 DLQ 定义——混合 DLQ/PQ。

SQS 可以像消息总线一样工作吗?

SQS 不能,但是有类似的产品可以。

    Amazon SNS

    SNS(Simple Notification Service)是一个通用的发布-订阅主题系统。 SNS 允许您创建主题,然后注册接收推送通知的订阅者。目前,推送通知可以采用 HTTP/S、电子邮件、SMS、SQS 和移动设备推送通知的形式。

    SNS 有一个相当健全的retry policy 用于 HTTP/S,但不支持 DLQ 或 PQ AFAIK。

    IronMQ's Push Queues

    IronMQ 是另一个 REST-ful 消息队列服务,比 SQS 功能更全面。 (真正的 FIFO 消息排序、更长的延迟等,但遗憾的是消息大小更小。)推送队列允许您设置推送“订阅者”,然后在任何时候将新消息放入队列时接收 HTTP POST。

    如果 IronMQ 无法传递消息——HTTP POST 超时,或者您的端点返回除2xx 之外的任何内容——那么它将重试传递。如果重试次数用完,它会将消息放入错误队列——在这种情况下是 DLQ 和 PQ 的组合。

    这可能与您在托管服务中接近真正的“ESB”一样接近。

当然,还有真正的开源 ESB 和 SOA 框架——MULE、ServiceMix 等等——但我不太了解你想要做什么那里有任何建议。 :)

【讨论】:

【参考方案2】:

在大多数情况下,我不确定是否需要区分 DLQPQ。事实上,我发现这个定义相当武断。对于大多数事务性消息传递实现,如果消息在指定的重试次数内未成功从队列中消耗掉,它将转到DLQ。为格式错误的消息设置一个单独的队列意味着您现在只有两个位置来查找未成功处理的消息,两个异常队列用于监控或操作注意事项,以及一些看起来可能属于其中一个的消息百分比队列(想到批处理场景)。

【讨论】:

【参考方案3】:

不,它不会像活动的 ESB 那样工作。根据定义,简单队列服务很简单。有一个“至少一次”的交付保证,但除此之外,它几乎没有做出任何承诺。

它仅用于轮询/长轮询。您可以拥有多个队列,每个队列服务于不同的目的,但单个队列非常简单,并不旨在为多个功能提供服务或提供高级逻辑。 SWF 可能提供您想要的,但您可能需要实施 ESB。

http://aws.amazon.com/swf/

【讨论】:

以上是关于Amazon SQS 死信队列:真的是死信还是毒药?的主要内容,如果未能解决你的问题,请参考以下文章

配置 SQS 死信队列以在收到消息时引发云监视警报

AWS SQS:当消费者发生错误时移动到死信队列

当 DLQ 尚不存在时,如何通过 Terraform 配置 SQS?

AWS SQS Boto3 手动将消息发送到死信

死信队列和退出队列有啥区别?

RabbitMQ----死信队列和延迟队列