使用boto处理SQS队列

9

我有一个使用boto库在EC2实例上的Python脚本,该实例是自动扩展组的一部分。该脚本处理来自SQS队列的消息:

import boto
from boto.sqs.message import Message

conn = boto.connect_sqs()
q = conn.create_queue('queue-name')

while (qin.count() > 0):
    m = q.get_messages()
    #do something with the message

使用while语句是否有意义?count()是否实时更新,例如:

  1. 其他实例从队列中取出信息(否则会重复)
  2. 新的消息添加到队列中(否则会错过它们)

如何使此脚本始终监听队列的新添加,即使队列为空?

在这个问题使用php脚本处理SQS队列中的项目中提到了'sqs ruby client library'有一个方法"poll",可以持续轮询队列,并在接收到队列中的消息时将其传递给一个块。Python中是否有类似的方法?

还建议使用SNS通知脚本消息队列的状态,但我不知道如何使用SNS配置响应系统,因为度量警报不够精细。


你知道哪个 Ruby 库吗?我想看看它。 - Hassek
抱歉,我只在上面链接的问题中看到了它。 - waigani
结账SNS - 推送比拉取更好。它们一起工作得非常好。http://docs.aws.amazon.com/sns/latest/dg/SendMessageToSQS.html - Gal Bracha
3个回答

7

您不应该依赖队列的计数,因为它仅旨在提供大约计数,并不能保证准确性。

如果您想要一直进行轮询,请使用以下方法:

while 1:
    messages = q.get_messages()
    # do something with messages
    time.sleep(N)

我已经添加了调用time.sleep的代码,以在循环中引入延迟。 N的值应至少为一秒钟,根据您期望新消息出现的速度,可能会更长。 如果您不在循环中放置某种延迟,您可能会因服务限制而开始被限制。
为避免多次读取消息,您应尝试调整队列的可见性超时时间,使其大于处理消息所需的时间,然后确保在处理完成后删除消息。

5

例子:

# wait_time_seconds count only 1 request in x seconds (0 - 20)
# num_messages get x messages in same request (1 - 10)
while 1:
    logger.info("... waiting messages ...")
    messages = queue_in.get_messages(wait_time_seconds=20, num_messages=10)
    for message in messages:
        logger.info('message: %s' % (message,))
        queue_in.delete_message(message)

3
  1. 当您从SQS中拉取消息时,该消息将变为不可见状态,并且其他队列查询无法访问它(编辑-不可见性可设置在0到12小时之间)。
  2. 每次添加新消息时,都必须重新获取队列,但这不应该是问题,因为排队服务首先存在的原因就是如此。

如果您想要不断轮询队列,请尝试所谓的“长轮询”Long Polling - 您可以进行持续轮询,最长达20秒,直到队列被填充才返回结果。

希望这能有所帮助,否则请查看boto sqs文档


消息的不可见性默认为30秒,而不是4天。并且这个时间段可以被修改。 - Jan Vlcinsky

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