Amazon SQS 可见性超时
当您从 Amazon SQS 队列接收到一条消息时,该消息仍然保留在队列中,但会暂时对其他使用者不可见。这种不可见性由可见性超时控制,用于确保在您处理该消息期间,其他使用者无法对其进行处理。Amazon SQS 提供了两种在处理后删除消息的选项:
-
手动删除 – 使用
DeleteMessage操作明确删除消息。 -
自动删除 – 在某些 Amazon SDK 中受支持,消息在成功处理后自动删除,从而简化工作流程。
可见性超时使用案例
管理长时间运行的任务 – 使用可见性超时来处理需要延长处理时间的任务。为需要延长处理时间的消息设置适当的可见性超时。这可确保在消息处理期间,其他使用者不会接收到该消息,从而防止重复工作并保持系统效率。
实现重试机制 – 通过编程方式延长在初始超时内未完成的任务的可见性超时。如果任务在初始可见性超时内未完成,您可以通过编程方式延长超时。这使您的系统能够重新尝试处理消息,同时又不会让其他使用者看到该消息,从而提高容错能力和可靠性。结合使用死信队列(DLQ)来管理持续故障。
协调分布式系统 – 使用 SQS 可见性超时来协调分布式系统中的任务。设置可见性超时,使其与不同组件的预期处理时间保持一致。这有助于保持一致性,并防止在复杂的分布式架构中出现竞争条件。
优化资源利用率 – 调整 SQS 可见性超时以优化应用程序中的资源利用率。通过设置适当的超时,您可以确保消息得到高效处理,避免不必要地占用资源。这可以提高整体系统性能和成本效益。
设置和调整可见性超时
可见性超时从消息送达给您时开始计算。在此期间,您需要处理并删除消息。如果您未在超时到期之前删除消息,该消息将在队列中再次变得可见,并且可以被其他使用者检索。队列的默认可见性超时为 30 秒,但您可以将其调整为您的应用程序处理和删除消息所需的时间。您也可以为每条消息设置特定的可见性超时,而无需更改队列的整体设置。根据需要,使用 ChangeMessageVisibility 操作通过编程方式延长或缩短超时。
传输中消息和配额
在 Amazon SQS 中,传输中消息是指已被使用者接收但尚未删除的消息。对于标准队列,传输中消息的数量上限约为 12 万条,具体取决于队列流量和消息积压情况。如果您达到此上限,Amazon SQS 会返回 OverLimit 错误,提示在删除某些传输中消息之前,无法接收更多的消息。对于 FIFO 队列,上限取决于活动消息组。
-
当使用短轮询时 – 如果使用短轮询时达到此上限,Amazon SQS 会返回
OverLimit错误,提示在删除某些传输中消息之前,无法接收更多的消息。 -
当使用长轮询时 – 如果您使用的是长轮询,当达到传输中消息数量上限时,Amazon SQS 不会返回错误。不过,在传输中消息的数量降到限制以下之前,它不会返回任何新消息。
要有效管理传输中消息,请执行以下操作:
-
及时删除 – 处理消息后将其删除(手动或自动),以便减少传输中消息的数量。
-
使用 CloudWatch 进行监控 – 设置警报,一旦传输中消息数量过高就触发警报,以防止达到上限。
-
分配负载 – 如果您处理的消息量很大,请使用额外的队列或使用者来平衡负载并避免出现瓶颈。
-
申请增加配额 – 如果需要提高上限,请向 Amazon Support 提交申请。
了解标准队列和 FIFO 队列中的可见性超时
在标准队列和 FIFO(先进先出)列队中,可见性超时都有助于防止多个使用者同时处理同一消息。但是,由于 Amazon SQS 采用“至少传递一次”模式,因此无法绝对保证在可见性超时期间消息不会被多次传递。
-
标准队列 – 在标准队列中,可见性超时有助于防止多个使用者同时处理同一消息。但是,由于 Amazon SQS 采用“至少传递一次”模式,因此无法保证在可见性超时期间消息不会被多次传递。
-
FIFO 队列 – 对于 FIFO 队列,具有相同消息组 ID 的消息将按严格的顺序处理。当具有消息组 ID 的消息处于传输中状态时,该组中的后续消息在传输中消息被删除或可见性超时到期后才可用。但是,这并不会无限期“锁定”该组 – 每条消息都按顺序处理,只有当每条消息被删除或再次变得可见时,该组中的下一条消息才可供使用者使用。这种方法可确保在组内进行有序处理,同时避免不必要地阻止该组传递消息。
处理故障
如果您未在可见性超时到期之前处理和删除消息(由于应用程序错误、崩溃或连接问题),则该消息将在队列中再次变得可见。届时,该消息可被同一或不同的使用者检索,进行下一次处理尝试。这可确保即使初始处理失败,消息也不会丢失。但是,如果将可见性超时设置得过高,则会延迟未处理的消息重新出现在队列中的时间,这可能导致重试过程变慢。请务必根据预期处理时间设置适当的可见性超时,以便及时处理消息。
更改和终止可见性超时
您可以使用 ChangeMessageVisibility 操作更改或终止可见性超时:
-
更改超时 – 使用
ChangeMessageVisibility动态调整可见性超时。这使您能够根据处理需求延长或缩短超时持续时间。 -
终止超时 – 如果您决定不处理接收到的消息,则可以通过
ChangeMessageVisibility操作将VisibilityTimeout设置为 0 秒,从而终止可见性超时。这样做可以立即使消息可供其他使用者处理。
最佳实践
使用以下最佳实践来管理 Amazon SQS 中的可见性超时,包括设置、调整和延长超时时间,以及使用死信队列(DLQ)处理未处理的消息。
-
设置和调整超时。首先,将可见性超时设置为您的应用程序处理和删除消息通常所需的最长时间。如果您不确定确切的处理时间,可以从较短的超时(例如 2 分钟)开始,然后根据需要延长。实施心跳机制来定期延长可见性超时,确保消息在处理完成之前保持不可见状态。这样做可以最大限度地减少重新处理未处理的消息时的延迟,并防止其过早变得可见。
-
延长超时时间并处理 12 小时限制。如果您的处理时间会有所变化或可能超过最初设置的超时,请在处理消息时使用
ChangeMessageVisibility操作延长可见性超时。请注意,可见性超时的最大限制为首次收到消息后的 12 小时。延长超时时间不会重置该 12 小时限制。如果您的处理时间超过该限制,可以考虑使用 Amazon Step Functions 或将任务拆分为更小的步骤。 -
处理未处理的消息。要管理多次处理尝试均失败的消息,请配置死信队列(DLQ)。这样做可以确保单独捕获在多次重试后仍无法处理的消息,以供进一步分析或处理,从而防止它们在主队列中反复出现。