我有一个SQS队列,需要不断监视传入消息。收到消息后,我会进行一些处理,并继续等待下一条消息。我通过在循环结束时设置一个2秒钟的无限循环来实现此目的。这行得通,但是我忍不住觉得这不是解决不断排队的需求的非常有效的方法。
代码示例:
while (1):
response = sqs.receive_message(
QueueUrl=queue_url,
AttributeNames=[
'SentTimestamp'
],
MaxNumberOfMessages=1,
MessageAttributeNames=[
'All'
],
VisibilityTimeout=1,
WaitTimeSeconds=1
)
try:
message = response['Messages'][0]
receipt_handle = message['ReceiptHandle']
# Delete received message from queue
sqs.delete_message(
QueueUrl=queue_url,
ReceiptHandle=receipt_handle
)
msg = message['Body']
msg_json = eval(msg)
value1 = msg_json['value1']
value2 = msg_json['value2']
process(value1, value2)
except:
pass
#print('Queue empty')
time.sleep(2)
为了干净地退出脚本(应该连续运行),我捕获了在Ctrl + C上触发的KeyboardInterrupt,并执行了一些清理例程以正常退出。
if __name__ == '__main__':
try:
main()
except KeyboardInterrupt:
logout()
是否有更好的方法来实现SQS队列的恒定轮询,是否需要2秒的延迟?我试图不敲打SQS服务,但这也许没关系吗?
答案 0 :(得分:1)
这最终就是SQS的工作方式-它需要进行轮询以获取消息。但有一些建议:
每次都不会只收到一条消息。做更多类似的事情:
messages = sqs.receive_messages(
MessageAttributeNames=['All'],
MaxNumberOfMessages=10,
WaitTimeSeconds=10
)
for msg in messages:
logger.info("Received message: %s: %s", msg.message_id, msg.body)
这会为您带来一些改变。第一件事是您愿意接收多达10条消息(这是一个呼叫中SQS的最大数目)。第二个是您将等待多达10秒钟来获取消息。来自SQS文档:
呼叫等待消息的持续时间(以秒为单位) 在返回之前到达队列。如果有消息,则 呼叫早于WaitTimeSeconds返回。如果没有可用消息 并且等待时间到期,呼叫成功返回,并显示为空 邮件列表。
因此,您不需要自己的sleep
呼叫-如果没有消息,则呼叫将等待直到其过期。相反,如果您有大量消息,那么您将尽快获得所有消息,因为您不会在代码中进行自己的sleep
调用。