aws lambda + SQS - 以并发为一体的批量消息传递

aws lambda + SQS - batch messaging with concurrency as one

我在 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 个立即得到处理(比如文件 1、文件 2、文件 3)
  2. 第二批(3 分钟后)被触发(比如文件 4、文件 5、文件 6)。不过当时第一批是运行。我可以看到日志 - “已经有 3 个作业 运行”。因此,它没有得到处理。根据代码,我也没有删除它。
  3. 现在,触发了第三批(比如文件 7、文件 8、文件 9)。此时,第一个批处理执行结束,因此所有 3 个都已成功处理并从队列中删除。

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

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

Does the message disappear from the queue if the event is triggered and not manually deleted?

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

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

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

通常最好设计一个能够优雅地处理异常并且不抛出异常的解决方案。但这取决于你的问题的细节。