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 队列保证“至少一次”处理。这意味着消息不会丢失,并且至少会处理一次。但是“至少一次”应该是什么意思?这是否意味着消息可以多次处理?嗯,答案是肯定的。
让我们首先看一下消息生命周期。以下是阶段:
- 消息被放入队列中。
- 它被消费者所接受。
- 处理后,使用者将其从队列中删除。
注意:在后处理时,消息不会自动删除,必须由使用者显式删除。
在阶段 #2 和 #3 之间,消息为“正在传输中”。当消息正在传输时,可见性超时会发挥作用,该超时会抑制队列中的消息,因此不会再次处理它。可以配置可见性超时,默认值为 30 秒。这个想法是,必须在可见性超时到期之前处理消息并随后从队列中删除,以避免重复处理。
但是,有时消息在处理过程中可能会卡住,从而导致可见性超时过期,并且消息被使用者再次拾取。此外,在删除过程中,可能会发生其中一台服务器脱离困境,并且消息位于该特定服务器上的情况。当它恢复时,消息将再次得到处理。因此,在使用标准 SQS 时,绝对有必要将应用程序设计为幂等的。也就是说,即使消息被多次处理,也不应产生任何业务影响。
回到我们的火车站示例,让我们假设一旦小组中的一个人拿到票,他就会给小组中的所有其他人发短信。但是,在发送文本时,如果其中一个接收者的手机断开网络,则该人将不会收到消息,并将再次购买门票。这是可以多次处理消息的常见方案。
另一方面,FIFO SQS 中的消息只处理一次。这就引出了另一个重要主题 — 如何处理重复邮件?标准 SQS 并不关心您是否输入重复的消息 — 下线应用程序应该是幂等的。
另一方面,FIFO队列不允许重复。它创建一个重复数据删除 ID,该 ID 本质上是基于有效负载的哈希值。但是,如果必须在较短的时间范围内处理相同的消息:默认重复数据删除 ID 将不起作用,并且必须创建自定义随机重复数据删除 ID,并允许处理传入的所有消息,即使它与前面的消息完全相同。
您应该使用哪种类型的 SQS?
根据经验,您应该始终使用标准 SQS。它是分布式的、冗余的,并且具有无限的吞吐量。毕竟,它旨在相当轻松地扩展和服务所有类型的工作负载。但是,如果严格的顺序对于您正在构建的应用程序至关重要,并且您不太关心吞吐量,那么显然,FIFO 将是您的最佳选择。