Amazon SQS 可见性超时 - Amazon Simple Queue Service
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

Amazon SQS 可见性超时

当使用者接收并处理来自队列的消息时,消息将保留在该队列中。Amazon SQS 不会自动删除消息。由于 Amazon SQS 是分布式系统,因此,无法保证使用者实际收到消息(例如,由于连接问题或由于使用者应用程序问题)。因此,使用者在接收和处理消息后必须从队列中删除该消息。

可见性超时

收到消息后,消息将立即保留在队列中。为防止其他使用者再次处理消息,Amazon SQS 设置了可见性超时,这是 Amazon SQS 防止所有使用者接收和处理消息的时间段。消息的默认可见性超时为 30 秒。最短时间为 0 秒。最长时间为 12 小时。有关使用控制台配置队列可见性超时的信息,请参阅配置队列参数(控制台)

注意

对于标准队列,可见性超时无法保证不会接收消息两次。有关更多信息,请参阅送t-least-once 货

FIFO 队列允许创建者或使用者尝试多次重试:

  • 如果创建者检测到 SendMessage 操作失败,则可以根据需要使用相同的消息重复数据删除 ID 重试发送多次。假设创建者在重复数据删除间隔到期之前至少收到一次确认,则多次重试既不会影响消息的顺序,也不会引入重复消息。

  • 如果使用者检测到 ReceiveMessage 操作失败,则可以根据需要使用相同的接收请求尝试 ID 重试多次。假设使用者在可见性超时到期之前至少收到一次确认,则多次重试不会影响消息的顺序。

  • 当您收到带有消息组 ID 的消息时,除非您删除该消息或该消息变为可见,否则不会再返回具有同一消息组 ID 的消息。

传输中消息

Amazon SQS 消息有三种基本状态:

  1. 创建者发送到队列。

  2. 使用者从队列中接收。

  3. 从队列中删除。

在消息由创建者发送到队列但使用者尚未从队列中接收(即在状态 1 和 2 之间)之后,会将消息视为存储。存储的消息数量没有配额。在消息由使用者从队列中接收但尚未从队列中删除(即在状态 2 和 3 之间)之后,会将消息视为传输中。传输中消息数量没有配额。

重要

适用于传输中消息的配额与无限数量的存储消息无关。

对于大多数标准队列(取决于队列流量和消息积压),最多可以有大约 120000 条传输中消息(使用者已从队列中接收,但尚未从队列中删除)。如果您在使用短轮询时达到此配额,则 Amazon SQS 会返回 OverLimit 错误消息。如果您使用长轮询,则 Amazon SQS 不返回任何错误消息。为避免达到此配额,您应该在处理消息后将其从队列中删除。您还可以增加用来处理消息的队列的数量。要申请提高配额,请提交支持请求

对于 FIFO 队列,最多可以有 20000 条传输中消息(使用者已从队列中接收,但尚未从队列中删除)。如果您达到此配额,Amazon SQS 将不会返回任何错误消息。

重要

使用 FIFO 队列时,如果在可见性超时窗口之外收到请求,则 DeleteMessage 操作将失败。如果可见性超时为 0 秒,则必须在消息发送的同一毫秒内将其删除,否则该消息将被视为放弃。这会在 MaxNumberOfMessages 参数大于 1 的情况下,导致 Amazon SQS 在对 ReceiveMessage 操作的同一响应中包含重复消息。有关更多详情,请参阅 Amazon SQS FIFO API 的工作原理

设置可见性超时

可见性超时从 Amazon SQS 返回消息时开始。在这段时间里,使用者可以处理和删除消息。但是,如果使用者在删除消息之前失败,并且您的系统没有在可见性超时结束之前对该消息调用 DeleteMessage 操作,则其他使用者将可以看到该消息并且再次接收该消息。如果某条消息只能被接收一次,则您的使用者应在可见性超时期间内删除该消息。

每个 Amazon SQS 队列都具有 30 秒的默认可见性超时设置。您可以为整个队列更改此设置。通常,您应将可见性超时设置为您的应用程序处理消息并从队列中删除消息所需的最长时间。此外,在接收消息时,您还可以为返回的消息设置特殊的可见性超时,而无需更改整个队列的超时。有关更多信息,请参阅及时处理消息部分中的最佳实践。

如果您不知道处理消息需要多长时间,请为您的使用者流程创建检测信号:指定初始可见性超时(例如 2 分钟),然后(只要您的使用者仍在处理该消息),就可以每分钟将可见性超时延长 2 分钟。

重要

最大可见性超时为从 Amazon SQS 收到 ReceiveMessage 请求时起 12 小时。延长可见性超时不会重置 12 小时的最大值。

此外,您可能无法将单个消息的超时时间设置为 ReceiveMessage 请求启动计时器后的整整 12 小时(即 43200 秒)。例如,如果您收到一条消息,并立即通过发送 ChangeMessageVisibility 调用,将 VisibilityTimeout 设置为 43200 秒,以设置 12 小时的最大值,则该消息很可能会失败。但是,除非通过 ReceiveMessage 请求消息和更新可见性超时之间存在明显的延迟,否则使用 43195 秒这个值会起到作用。如果您的使用者需要超过 12 小时,请考虑使用 Step Functions。

更改消息的可见性超时

当您收到来自队列的消息并开始处理该消息时,队列的可见性超时可能不够(例如,您可能需要处理和删除消息)。可通过使用 ChangeMessageVisibility 操作指定新的超时值来缩短或延长消息的可见性。

例如,如果队列的默认超时值为 60 秒,在您接收消息后 15 秒时,您发送了 ChangeMessageVisibility 调用并将 VisibilityTimeout 设为 10 秒,则这 10 秒从您进行 ChangeMessageVisibility 调用时开始计时。因此,自您最初更改可见性超时后 10 秒(共 25 秒)起,任何更改可见性超时或删除此消息的尝试都可能导致错误。

注意

新的超时期限自您调用 ChangeMessageVisibility 操作起生效。此外,新的超时期限仅应用于消息的特定接收。ChangeMessageVisibility 不会影响消息的后续接收或后续队列的超时。

终止消息的可见性超时

收到来自某个队列的某条消息时,您可能会发现,您实际上不想处理并删除该消息。Amazon SQS 允许您终止特定消息的可见性超时。这将使该消息对系统中的其他组件立即可见并且可用于处理。

要在调用 ReceiveMessage 后终止消息的可见性超时,请调用 ChangeMessageVisibility 并将 VisibilityTimeout 设置为 0 秒。