Amazon Simple Queue Service
开发人员指南
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 Amazon AWS 入门

使用 Amazon SQS 消息

下列准则可帮助您使用 Amazon SQS 高效地处理消息。

及时处理消息

可见性超时设置取决于您的应用程序需要多长时间来处理和删除消息。例如,如果您的应用程序处理一条消息需要花费 10 秒,并且您将可见性超时设置为 15 分钟,则在上一次处理尝试失败的情况下,您必须等待一个相对较长的时间才能再次尝试处理消息。或者,如果您的应用程序处理一条消息需要花费 10 秒,但您将可见性超时仅设置为 2 秒,则当原始使用者仍在处理消息时,另一个使用者会收到重复消息。

要确保有足够的时间处理消息,请使用下列策略之一:

  • 如果您知道 (或者可以合理地估计) 处理消息所需的时间,则将消息的可见性超时 延长至处理消息所需的最长时间并删除消息。有关更多信息,请参阅配置可见性超时更改消息的可见性超时

  • 如果您不知道处理消息所需的时间,请为创建使用者处理创建检测信号:指定初始可见性超时 (例如,2 分钟),然后每一分钟将可见性超时延长 2 分钟,前提是您的使用者仍在处理消息。

注意

如果需要将可见性超时延长至最多 12 小时,请考虑使用 AWS Step Functions

处理请求错误

要处理请求错误,请使用下列策略之一:

  • 如果您使用 AWS 开发工具包,则已经可以任意使用自动重试和回退 逻辑。有关更多信息,请参阅 Amazon Web Services 一般参考 中的 AWS 中的错误重试和指数回退

  • 如果未使用 AWS 开发工具包功能进行重试和回退,则在未收到任何消息、收到超时或收到来自 Amazon SQS 的错误消息的情况下重试 ReceiveMessage 操作之前,应允许暂停(例如,200 毫秒)。对于将产生相同结果的 ReceiveMessage 的后续使用,应允许更长的暂停时间 (例如 400 毫秒)。

设置长轮询

长轮询 通过消除空响应的数量 (ReceiveMessage 请求时没有消息可用时) 并消除假的空响应 (消息可用但未包含在响应中) 来帮助降低您使用 Amazon SQS 的成本。有关更多信息,请参阅 Amazon SQS 长轮询

要确保最佳消息处理,请使用以下策略:

  • 在大多数情况下,您可以将 ReceiveMessage 等待时间设置为 20 秒。如果 20 秒对您的应用程序来说太长,则可设置较短的 ReceiveMessage 等待时间 (最少 1 秒)。如果不使用 AWS 开发工具包访问 Amazon SQS,或者将 AWS 开发工具包配置为具有较短的等待时间,则可能必须修改 Amazon SQS 客户端,才能允许时间更长的请求或对长轮询使用较短的等待时间。

  • 如果您对多个队列实施长轮询,则对每个队列使用一个线程,而不是对所有队列使用单个线程。如果对每个队列使用一个线程,您的应用程序将能够在各队列中的消息可用时处理这些消息;如果使用单个线程来轮询多个队列,则可能导致应用程序在等待 (最长 20 秒) 没有任何可用消息的队列时无法处理其他队列中的可用消息。

捕获有问题的消息

要捕获所有无法处理的消息,并确保 CloudWatch 指标的正确性,请配置一个死信队列

  • 在源队列无法将消息处理指定次数后,重新驱动策略会将消息重定向到死信队列。

  • 使用死信队列将减少消息数并减小向您公开毒丸消息 (可接收但无法处理的消息) 的几率。

  • 在队列中包含毒丸消息可能导致 ApproximateAgeOfOldestMessage CloudWatch 指标失真,因为它会提供不正确的毒丸消息存在时间。配置死信队列有助于避免在使用此指标时发出错误警报。

设置死信队列保留期

消息的过期始终基于其原始排队时间戳。当邮件移动到死信队列时,排队时间戳保持不变。例如,如果消息在移动到死信队列之前在原始队列中花费了 1 天,并且死信队列的保留期设置为 4 天,则在 3 天后,邮件将从死信队列中删除。因此,最佳做法是始终将死信队列的保留期设置为长于原始队列的保留期。

避免不一致的消息处理

在配置死信队列时,避免以下情况:标准队列的消息处理不一致以及将最大接收次数设置为 1。

重要

在某些不常发生的场景中,如果您将最大接收次数设置为 1,则不管何时 ReceiveMessage 调用失败,消息都可能不被接收而移动到死信队列中。

实施请求-响应系统

实施请求-响应和远程程序调用 (RPC) 系统时,请记住以下最佳实践:

  • 请勿为每个消息 创建回复队列。而是在启动时为每个创建者创建回复队列,使用关联 ID 消息属性将回复映射到请求。

  • 不要让生成者共享回复队列。这可能会导致生成者收到针对另一个生成者的响应消息。