探索 Amazon SQS 的架构

Posted 小小怪物

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了探索 Amazon SQS 的架构相关的知识,希望对你有一定的参考价值。

在本文中,了解 Amazon SQS 的工作原理以及如何使用它来创建分布式应用程序,探索 SQS 的组件及其架构。

什么是 Amazon SQS?

Amazon SQS(简单队列服务)是一种消息队列服务,它使应用程序组件能够通过交换消息来相互通信。这广泛用于在 AWS 上构建事件驱动型系统或分离服务。

Amazon SQS 的功能

  • 消息持久性:消息存储在队列中,直到发送或接收终结点传递或删除消息。
  • 有保证的消息传递:消息至少传递一次,并且传递顺序与发送顺序相同。
  • 邮件重新传递:如果邮件未被确认,则在从队列中删除之前,最多会重新发送三次。
  • 可见性超时:可以将邮件设置为过期并在设定的时间后删除,即使它们尚未送达。

Amazon SQS 的优势

Amazon SQS 是一种高度可靠且可扩展的消息队列服务,使您能够可靠地连接应用程序。它具有以下优点:

  • 成本低:Amazon SQS 具有即用即付定价模式以及使用任何 AWS 服务的能力,因此具有成本效益。
  • 高吞吐量:每秒可处理超过 1 万条消息,延迟低于 1 毫秒。
  • 容错:该服务设计为高可用性和持久性,没有单点故障。
  • 安全性:Amazon SQS 在客户端之间发送消息时使用 TLS 和消息签名,以及用于访问服务的客户端的身份验证机制。

如何使用 SQS 以 FIFO 顺序处理消息

等等,队列不是设计上应该是先进先出的吗?嗯,是的,但是使用 SQS,它变得有点复杂。AWS声称他们尽最大努力按顺序处理消息,但是,有时可能会有消息不按顺序处理的情况。 SQS 具有具有大量冗余的分布式架构。这意味着有多个邮件存储。在运行时,消息是从其中一个存储中随机选取的。

让我尝试用类比更好地解释这一点。假设一行三人去火车站售票柜台买票。他们决定站在三个不同的队列中,谁先拿到票,谁就会通知其他人,这样他们就可以从队列中出来——分布式和冗余。让我们假设所有三个队列在该实例中都有相同数量的人。幸运的是,另一组三个人几乎同时进入车站。当他们分成三个队列时,第二组的一个人设法越过了第一组,并在其中一个队列中领先。轮到他们时,第二组的人先于另一组人拿到了票——这不是想要的,但有时会发生。

类比

那么,出路在哪里呢?如果需要严格的 FIFO 订单,AWS 建议使用 FIFO 队列。与标准 SQS 不同,FIFO SQS 保证严格的排序。

打个比方,假设你走进一家银行,立即被交出一个代币。代币持有者按顺序送达,排除了某人不按顺序送达的可能性。

如何处理消息?

标准 SQS 队列保证“至少一次”处理。这意味着消息不会丢失,并且至少会处理一次。但是“至少一次”应该是什么意思?这是否意味着消息可以多次处理?嗯,答案是肯定的。

让我们首先看一下消息生命周期。以下是阶段:

  1. 消息被放入队列中。
  2. 它被消费者所接受。
  3. 处理后,使用者将其从队列中删除。

注意:在后处理时,消息不会自动删除,必须由使用者显式删除。

在阶段 #2 和 #3 之间,消息为“正在传输中”。当消息正在传输时,可见性超时会发挥作用,该超时会抑制队列中的消息,因此不会再次处理它。可以配置可见性超时,默认值为 30 秒。这个想法是,必须在可见性超时到期之前处理消息并随后从队列中删除,以避免重复处理。

但是,有时消息在处理过程中可能会卡住,从而导致可见性超时过期,并且消息被使用者再次拾取。此外,在删除过程中,可能会发生其中一台服务器脱离困境,并且消息位于该特定服务器上的情况。当它恢复时,消息将再次得到处理。因此,在使用标准 SQS 时,绝对有必要将应用程序设计为幂等的。也就是说,即使消息被多次处理,也不应产生任何业务影响。

回到我们的火车站示例,让我们假设一旦小组中的一个人拿到票,他就会给小组中的所有其他人发短信。但是,在发送文本时,如果其中一个接收者的手机断开网络,则该人将不会收到消息,并将再次购买门票。这是可以多次处理消息的常见方案。

另一方面,FIFO SQS 中的消息只处理一次。这就引出了另一个重要主题 — 如何处理重复邮件?标准 SQS 并不关心您是否输入重复的消息 — 下线应用程序应该是幂等的。

另一方面,FIFO队列不允许重复。它创建一个重复数据删除 ID,该 ID 本质上是基于有效负载的哈希值。但是,如果必须在较短的时间范围内处理相同的消息:默认重复数据删除 ID 将不起作用,并且必须创建自定义随机重复数据删除 ID,并允许处理传入的所有消息,即使它与前面的消息完全相同。

您应该使用哪种类型的 SQS?

根据经验,您应该始终使用标准 SQS。它是分布式的、冗余的,并且具有无限的吞吐量。毕竟,它旨在相当轻松地扩展和服务所有类型的工作负载。但是,如果严格的顺序对于您正在构建的应用程序至关重要,并且您不太关心吞吐量,那么显然,FIFO 将是您的最佳选择。

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

【中文标题】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 的架构的主要内容,如果未能解决你的问题,请参考以下文章

TiDB Operator + Amazon Web Service,探索云原生数据库的最佳实践

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

Amazon MQ 和 SQS 有啥区别?

SimpleMessageListenerContainer Amazon SQS Pollinterval

Amazon SQS/SNS 策略错误

如何将Amazon SQS与Dynamodb集成