使用无限循环不断轮询SQS队列

时间:2020-08-26 16:18:57

标签: python amazon-sqs

我有一个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服务,但这也许没关系吗?

1 个答案:

答案 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调用。