Amazon SQS 中的 FIFO 队列传递逻辑
以下概念阐明了 Amazon SQS FIFO 队列如何处理消息的发送和接收,尤其是在处理消息排序和消息组 ID 时。
发送消息
Amazon SQS FIFO 队列使用唯一的重复数据删除 ID 和消息组 ID 来保留消息顺序。本主题重点介绍了消息组 ID 对保持组内严格排序的重要性,并重点介绍了确保在多个生创建者之间可靠有序地传递消息的最佳实践。
-
顺序保存
-
当具有唯一重复数据删除 ID 的多条消息连续发送到 FIFO 队列时,Amazon SQS 将存储这些消息并确认其传输。随后,这些消息将按其确切的传输顺序进行接收和处理。
-
-
消息组 ID
-
在 FIFO 队列中,消息基于其消息组 ID 进行排序。如果多个创建者或线程发送具有相同消息组 ID 的消息,Amazon SQS 会确保按照消息的到达顺序进行存储和处理。
-
最佳实践:为确保多个创建者之间的严格消息顺序,应为来自每个创建者的所有消息分配唯一的消息组 ID。
-
-
按组排序
-
FIFO 队列逻辑应用于每个消息组 ID:
-
每个消息组 ID 表示一个不同的、有序的消息组。
-
在每一个消息组 ID 内,所有消息的发送和接收均严格遵循一定的顺序。
-
具有不同消息组 ID 的消息可能以不同于彼此的顺序到达或进行处理。
-
-
要求:您必须将消息组 ID 与每条消息关联。如果消息发送时未指定消息组 ID,则操作将失败。
-
单个组场景:如果需要严格遵循一定的顺序处理所有消息,请为每条消息使用相同的消息组 ID。
-
接收消息
Amazon SQS FIFO 队列处理消息检索,包括批处理、FIFO 顺序保证以及对请求特定消息组 ID 的限制。本主题介绍了 Amazon SQS 如何严格遵守排序和可见性规则,同时检索消息组 ID 内和跨消息组 ID 的消息。
-
批量检索
-
当接收来自具有多个消息组 ID 的 FIFO 队列的消息时,Amazon SQS:
-
尝试在单次调用中返回尽可能多的具有相同消息组 ID 的消息。
-
允许其他使用者并行处理来自不同消息组 ID 的消息。
-
-
重要澄清
-
您可以一次性收到来自同一消息组 ID 的多条消息(使用
MaxNumberOfMessages参数,一次调用最多可接收 10 条消息)。 -
但是,在后续请求中,您无法接收来自同一消息组 ID 的其他消息,除非:
-
当前接收到的消息被删除,或
-
它们再次变为可见(例如,在可见性超时结束之后)。
-
-
-
-
FIFO 顺序保证
-
批量检索的消息在组中保留其 FIFO 顺序。
-
如果同一个消息组 ID 的可用消息少于 10 条,Amazon SQS 可能会在同一批次中包含来自其他消息组 ID 的消息,但每个组都保留 FIFO 顺序。
-
-
使用者限制
-
您无法显式请求接收具有特定消息组 ID 的消息。
-
多次重试
创建者和使用者可以安全地重试 Amazon SQS FIFO 队列中失败的操作,而不会打乱消息顺序或引入重复消息。本主题还重点介绍了重复数据删除 ID 和可见性超时如何在重试期间确保消息的完整性。
-
产生器重试
-
如果
SendMessage操作失败,创建者可以使用相同的消息重复数据删除 ID 多次重试发送消息。 -
只要创建者在重复数据删除间隔到期前收到至少一个确认,重试操作将:
-
不会引入重复消息。
-
不会打乱消息顺序。
-
-
-
消费端重试
-
如果
ReceiveMessage操作失败,使用者可以根据需要使用相同的接收请求尝试 ID 重试多次。 -
只要使用者在可见性超时结束之前收到至少一次确认,则重试:
-
不会打乱消息顺序。
-
-
关于 FIFO 行为的其他注意事项
了解如何处理可见性超时,支持使用多个消息组 ID 进行并行处理,以及确保在单个组场景中遵循严格的顺序进行处理。
-
处理可见性超时
-
当消息被检索但未删除时,将保持不可见状态,指导可见性超时结束。
-
在第一条消息被删除或再次可见之前,系统不会返回来自同一消息组 ID 的其他消息。
-
-
并发和并行处理
-
FIFO 队列支持并行处理来自不同消息组 ID 的消息。
-
为最大化并发性能,请在系统设计中采用多个消息组 ID 来实现独立工作流。
-
-
单个组场景
-
要严格按顺序处理 FIFO 队列中的所有消息,请为队列中的所有消息使用单个消息组 ID。
-
示例(帮助更好地理解)
以下实际场景演示了 Amazon SQS 中 FIFO 队列行为。
-
场景 1:单个组 ID
-
创建者发送了 5 条具有相同消息组 ID(Group A)的消息。
-
使用者按照 FIFO 顺序接收这些消息。在使用者删除这些消息或可见性超时结束之前,不会接收来自 Group A 的其他消息。
-
-
场景 2:多个组 ID
-
创建者向 Group A 发送了 5 条消息,向 Group B 发送了 5 条消息
-
Consumer 1 处理来自 Group A 的消息,而 Consumer 2 处理来自 Group B 的消息。这实现了并行处理,并在每个组内保持严格的顺序。
-
-
场景 3:批量检索
-
创建者向 Group A 发送了 7 条消息,向 Group B 发送了 3 条消息
-
单个使用者最多可检索 10 条消息。如果队列允许,它可能会返回:
-
来自 Group A 的 7 条消息和来自 Group B 的 3 条消息(如果单组可用的消息不足,则返回的数量更少)。
-
-