如何使用boto长轮询亚马逊sqs服务?

4
我在亚马逊上有一个SQS队列,有几个消费者正在轮询它。
最近我发现numberofEmptyReceives已经达到了一千万次,这意味着我需要为这些请求付费。
以下是我消费消息的方式。
while True:
    for message in queue.receive_messages(AttributeNames=['All'], MaxNumberOfMessages=10):

我知道有WaitTimeSeconds选项,但文档似乎表明它不进行长轮询。
等待消息到达队列的持续时间(以秒为单位),然后才返回调用。如果有消息可用,则调用比WaitTimeSeconds更快地返回。如果没有消息可用且等待时间过期,则调用成功返回一个空消息列表。
特别是
如果有消息可用,则调用比WaitTimeSeconds更快地返回。
从上面的句子中可以看出,似乎boto3仍会调用sqs来检查是否有消息。
使用boto3进行长轮询的正确方法是什么,以避免请求费用?
设置thread.sleep就这么简单吗?
我还找不到github上的源代码。

这个问题没有简单的解决方案。如果您有大量的批处理消息,使用SQS触发Lambda可能会过度杀伤。增加轮询时间可能意味着服务响应缓慢。您需要自己做出合理的解释。 - mootmoot
1个回答

7

只需在您的 receive_message 调用中发送一个 WaitTimeSeconds 参数(最多20秒)。来自AWS文档:

# Long poll for message on provided SQS queue
response = sqs.receive_message(
    QueueUrl=queue_url,
    AttributeNames=[
        'SentTimestamp'
    ],
    MaxNumberOfMessages=1,
    MessageAttributeNames=[
        'All'
    ],
    WaitTimeSeconds=20
)

如果队列中没有消息,则调用将等待最长 WaitTimeSeconds 时间,直到消息出现。如果在时间到期之前出现消息,则调用会立即返回该消息。
有关更多详细信息,请参见在Amazon SQS中启用长轮询
您仍将为长轮询请求付费,但节省的成本在于执行一个可计费的SQS操作,并等待长轮询超时,否则您可能需要在相同时间段内执行两个或三个甚至更多的可计费操作。

1
抱歉,我有点困惑,“如果在时间到期之前出现消息,则调用将立即返回该消息。” 如何实现上述语句,而不需要持续轮询,因为SQS没有将消息推送到我的服务器的能力?如果它确实在进行持续轮询,那么为什么它的请求比简单地不等待“WaitTimeSeconds”要少? - J L
在深层次上,API 可能正在进行持续轮询。在第一百万个请求之后,每百万个请求的费用约为 0.40 美元,我从未需要进行验证。但是,在长轮询的合同下,您不需要为该活动付费。 - craigcaulfield

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接