为队列限制工人的速率(例如:SQS)

时间:2017-02-01 12:40:16

标签: amazon-web-services aws-lambda amazon-sqs

每天,我都会有一个CRON任务运行,它填充了一个SQS队列,其中包含许多需要实现的任务。所以(例如)每天早上9点,空队列将收到约100条需要处理的消息。

我想让新工作者每秒旋转一次,直到队列为空。如果任何任务失败,则将其放在队列的后面以重新运行。

例如,如果每个任务最多需要1.5秒才能完成:

  • 1秒后,1名工作人员将启动消息A
  • 2秒后,1名工作人员可能仍在运行消息A,1名工作人员将开始运行消息B
  • 100秒后,1名工作人员可能仍在运行消息XX,1名工作人员将因为先前失败而接收消息
  • 101秒后,第二天早上不再传播工人

有没有办法在AWS lambda中配置这种类型的基础架构?

3 个答案:

答案 0 :(得分:2)

一种方式,虽然我不相信它是最佳的:

由CloudWatch事件触发的lambda(例如每秒或每10秒,具体取决于您的速率限制)。哪个民意调查SQS接收(最多)N个消息,然后"粉丝输出"与每条消息的另一个Lambda函数。

一些伪代码:

# Lambda 1 (schedule by CloudWatch Event / e.g. CRON)
def handle_cron(event, context):
    # in order to get more messages, we might have to receive several times (loop)
    for message in queue.receive_messages(MaxNumberOfMessages=10):
        # Note: the Event InvocationType so we don't want to wait for the response!
        lambda_client.invoke(FunctionName="foo", Payload=message.body, InvocationType='Event')

# Lambda 2 (triggered only by the invoke in Lambda 1)
def handle_message(event, context):
    # handle message
    pass

答案 1 :(得分:1)

对我来说,你最好将消息发布到SNS,而不是SQS,然后让你的lambda函数订阅SNS主题。

让Lambda担心响应负载需要旋转多少'实例'。

以下是关于此方法的一篇博客文章,但谷歌可能会帮助您找到更接近实际用例的博客。

https://aws.amazon.com/blogs/mobile/invoking-aws-lambda-functions-via-amazon-sns/

答案 2 :(得分:0)

为什么不让Lambda函数在上午9点开始轮询sqs,一次获取一条消息并在每条消息之间休息一秒?死信队列可以处理重试。在x秒后没有收到来自SQS的消息后停止执行。

这是一个独特的案例,您实际上并不想要并行处理。