本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
处理 Amazon SQS 消息
下列准则可帮助您使用 Amazon SQS 高效地处理消息。
及时处理消息
可见性超时设置取决于您的应用程序需要多长时间来处理和删除消息。例如,如果您的应用程序处理一条消息需要花费 10 秒,并且您将可见性超时设置为 15 分钟,则在上一次处理尝试失败的情况下,您必须等待一个相对较长的时间才能再次尝试处理消息。或者,如果您的应用程序处理一条消息需要花费 10 秒,但您将可见性超时仅设置为 2 秒,则当原始使用者仍在处理消息时,另一个使用者会收到重复消息。
要确保有足够的时间处理消息,请使用下列策略之一:
-
如果您知道 (或者可以合理地估计) 处理消息所需的时间,则将消息的可见性超时 延长至处理消息所需的最长时间并删除消息。有关更多信息,请参阅 。配置可见性超时.
-
如果您不知道处理消息需要多长时间,请创建一个心跳对于你的消费者流程:指定初始可见性超时(例如 2 分钟),然后,只要您的消费者仍在处理消息,就可以每分钟将可见性超时延长 2 分钟。
重要
最大可见性超时为从 Amazon SQS 收到
ReceiveMessage
请求. 延长可见性超时不会重置 12 小时的最大值。此外,您可能无法将单条消息的超时设置为整整 12 小时(例如 43,200 秒),因为
ReceiveMessage
请求启动计时器。例如,如果您收到消息并立即通过发送一个ChangeMessageVisibility
使用调用VisibilityTimeout
等于 43,200 秒,它可能会失败。但是,使用值 43,195 秒将起作用,除非通过以下方式请求消息之间存在显著延迟。ReceiveMessage
并更新可见性超时。如果您的使用者需要超过 12 小时,请考虑使用 Step Functions。
处理请求错误
要处理请求错误,请使用下列策略之一:
-
如果您使用Amazon开发工具包,您已有自动重试和退避逻辑可供你使用。有关退避技术的信息,请参阅亚马逊云科技一般参考中的 Amazon 中的错误重试和指数回退。
-
如果您未使用Amazon重试和回退的开发工具包功能,请允许暂停 (例如,200 毫秒),然后重试ReceiveMessage未收到来自 Amazon SQS 的消息、超时或错误消息后的操作。对于将产生相同结果的
ReceiveMessage
的后续使用,应允许更长的暂停时间 (例如 400 毫秒)。
设置长轮询
当等待时间ReceiveMessage
API 操作大于 0,长轮询实际上。轮询等待时间最长为 20 秒。长轮询通过消除空响应的数量 (如果没有消息可用时) 来帮助降低您使用 Amazon SQS 的成本。ReceiveMessage
请求) 和假的空响应 (消息可用但未包含在响应中)。有关更多信息,请参阅 Amazon SQS 短轮询和长轮询。
要获得最佳消息处理,请使用下列策略:
-
在大多数情况下,您可以将
ReceiveMessage
等待时间设置为 20 秒。如果 20 秒对您的应用程序来说太长,则可设置较短的ReceiveMessage
等待时间 (最少 1 秒)。如果您未使用Amazon用于访问 Amazon SQS 的开发工具包,或者如果您配置了Amazon要缩短开发工具包的等待时间,则可能必须修改 Amazon SQS 客户端,才能允许时间更长的请求或对长轮询使用较短的等待时间。 -
如果您对多个队列实施长轮询,则对每个队列使用一个线程,而不是对所有队列使用单个线程。如果对每个队列使用一个线程,您的应用程序将能够在各队列中的消息可用时处理这些消息;如果使用单个线程来轮询多个队列,则可能导致应用程序在等待 (最长 20 秒) 没有任何可用消息的队列时无法处理其他队列中的可用消息。
重要
要避免 HTTP 错误,请确保ReceiveMessage
请求长于WaitTimeSeconds
参数。有关更多信息,请参阅 。ReceiveMessage.
捕获有问题的消息
要捕获所有无法处理的消息并收集准确的消息CloudWatch指标,配置死信队列.
-
在源队列无法将消息处理指定次数后,重新驱动策略会将消息重定向到死信队列。
-
使用死信队列将减少消息数并减小向您公开毒丸消息 (可接收但无法处理的消息) 的几率。
-
在队列中包含毒丸消息可能导致 ApproximateAgeOfOldestMessage CloudWatch 指标失真,因为它会提供不正确的毒丸消息存在时间。配置死信队列有助于避免在使用此指标时发出错误警报。
设置死信队列保留期
消息的过期时间始终基于其原始入队时间戳。将消息移至死信队列时,入队时间戳将不变。这些区域有:ApproximateAgeOfOldestMessage
指标指示消息何时移动到死信队列,不最初发送消息的时间。例如,假设消息在原始队列中花费 1 天时间,然后才移动到死信队列。如果死信队列的保留期为 4 天,则该消息将在 3 天后从死信队列中删除,而ApproximateAgeOfOldestMessage
是 3 天。因此,最佳做法是始终将死信队列的保留期限设置为长于原始队列的保留期。
避免不一致的消息处理
由于 Amazon SQS 是一个分布式系统,因此即使 Amazon SQS 将消息标记为已发送,使用者也可能不会收到消息。ReceiveMessage
API 方法调用。在这种情况下,Amazon SQS 将消息记录为至少已发送一次,即使使使用者从未收到过也是如此。由于在这些情况下不会再尝试发送消息,因此我们不建议将死信队列的最大接收数量设置为 1。
实施请求-响应系统
实施请求-响应和远程程序调用 (RPC) 系统时,请记住以下最佳实践:
-
请勿为每个消息 创建回复队列。而是在启动时为每个创建者创建回复队列,使用关联 ID 消息属性将回复映射到请求。
-
不要让生成者共享回复队列。这可能会导致生成者收到针对另一个生成者的响应消息。
有关使用临时队列客户端实施请求-响应模式的更多信息,请参阅 请求-响应消息收发模式(虚拟队列)。