我在EC2上运行了一个带有2个不同python脚本的盒子,它们使用2个不同的SQS队列。我的脚本在上周工作非常好,因为突然其中一个脚本需要太长时间来从SQS队列中提取消息。即使它设法拉取消息,它也会引发大量重复的消息。我的2个脚本使用相同的方法:
def getMessages(self, n):
'''returns n messages erasing them, mutliple of 10'''
msgs=[]
rs=self.queue.get_messages(10)
if len(rs) < 1:
return []
count = 0
while count < n or len(rs) < 10:
msgs.extend(rs)
rs=self.queue.get_messages(10)
count += 10
# delete pulled messages
for msg in msgs:
self.queue.delete_message(msg)
return msgs
在这种情况下,self.queue是以下实例:
self.conn = SQSConnection(SQS_ACCESS_KEY, SQS_SECRET_KEY)
self.queue = self.conn.get_queue(queue_name)
我的脚本使用方法getMessages(),方法如下:
while True:
print 'Getting SQS messages'
messages = sqs.getMessages(50)
print 'Got %s messages' % len(messages)
for msg in messages:
do_something(msg)
print 'Going to sleep'
time.sleep(sleep_time)
现在,我的脚本只需要很长时间来提取消息,它会打印Getting SQS messages
,有时会在那里停留几个小时。令我们更奇怪的是,如果我打开一个ipython shell并执行getMessages(50)
它运行得非常快,而我的其他脚本完全相同,但在不同的队列上,我绝对没有问题。
这里可能有什么问题,谢谢。
答案 0 :(得分:3)
你在while循环中的getMessages函数中有一些错误:
1.使用count += len(rs)
2.主要错误:你不需要
or len(rs) < 10
条件是因为SQS最多可以获得10条消息,如果您的队列已满,每次获得10条消息,您将获得无限循环。
此外,我认为您应该考虑使用yield
语句来返回消息,处理消息并在处理完消息之后,将它们从队列中删除。
另外一件事,检查if len(rs) < 1:
的pythonic方式是if not rs: