aws lambda + SQS - 并发的批处理消息

时间:2021-02-15 17:32:50

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

我在 lambda 中设置了一个 sqs 触发器

batch size : 3

batch window : 300 seconds

concurrency: 1

SQS 队列设置为

visiblity timeout: 3 minutes

这里的想法是一次处理 3 个文件。

这是 lambda 代码的样子

def lambda_handler(event, context):
    
    maximum_jobs = 3
    sqs_client = boto3.client(
        'sqs'
    )
    
    
    for i in range(len(event["Records"])):
        msg_string = event["Records"][i]["body"]
        
        
        if get_active_executions() < maximum_jobs:

        start_execution()
                
        receipt_handle = event["Records"][i]["receiptHandle"]
        
        delete_sqs_message(sqs_client, "myqueue",  receipt_handle)
   
        
        else:
            print(f"Already {maximum_jobs}  jobs running")
        
    
    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }

为了测试成功场景,我将 6 个条目推入队列。

  1. 立即处理前 3 条消息,并从队列中删除前 3 条消息。
  2. 其他 3 个正在等待飞行模式(因为我将并发设置为 1,批大小设置为 3)
  3. 在 3 分钟的可见性超时后,剩余的 3 条消息返回到队列中,触发器拾取了剩余的 3 个文件。剩下的 3 个也被删除了。
  4. 所有 6 个文件均已成功处理。

现在,我用 9 个文件测试了相同的代码

  1. 前 3 个被立即处理(比如 file1、file2、file3)
  2. 第二批(3 分钟后)被触发(比如 file4、file5、file6)。然而当时,第一批正在运行。我可以看到日志 - “已经有 3 个作业在运行”。因此,它没有得到处理。根据代码,我也没有删除它。
  3. 现在,第三批被触发(比如 file7、file8、file9)。此时,第一批执行结束,因此所有 3 个都被成功处理并从队列中删除。

我期待在 3 分钟内再次触发批处理(文件 4、文件 5、文件 6)。然而,它并没有发生。我注意到队列是空的。

如果事件被触发而不是手动删除,消息是否会从队列中消失?什么是预期的行为。我在代码中遗漏了什么吗?

1 个答案:

答案 0 :(得分:2)

<块引用>

如果事件被触发而不是手动删除,消息是否会从队列中消失?

当 lambda 成功处理一个批处理时,批处理中的所有消息都会从队列中删除。

可以删除 lambda 函数内的消息,但通常不需要。

如果 lambda 抛出异常,消息(未被 lambda 删除)将在可见性超时后“返回”到可见队列。

设计一个优雅地处理异常而不抛出异常的解决方案通常会更好。但这取决于您的问题的详细信息。