【问题标题】:aws lambda + SQS - batch messaging with concurrency as oneaws lambda + SQS - 以并发为一体的批量消息传递
【发布时间】:2021-02-16 21:30:38
【问题描述】:

我在 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)。然而,这并没有发生。我注意到队列是空的。

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

【问题讨论】:

  • start_execution() 发生了什么?您是否在 Lambda 函数之外触发了另一个任务?如果是这样,你需要等待吗?听起来有点像getActiveExecutions() 正在检查某个外部任务是否正在运行,并且此任务花费的时间比预期的要长,因此您看到此Already 3 jobs running 是因为您没有等待第一批任务完成。
  • 另一个问题:如果 SQS 使用一条或多条消息触发您的 Lambda,并且您的 Lambda 函数没有抛出错误,SQS 将自动从队列中删除消息。 IE。您无需在代码中删除它们,它会自动完成。另请参阅:docs.aws.amazon.com/lambda/latest/dg/with-sqs.htmlWhen your function successfully processes a batch, Lambda deletes its messages from the queue
  • 哦!!。第二批没有抛出错误。因此消息被 lambda 从队列中删除。我应该如何处理这种情况?我希望他们回到队列中。我是否需要重新插入或在 lambda 中抛出错误,以便它不会从队列中删除。
  • 不确定您的用例和处理顺序的效果,但在这里抛出异常很好,但可能并不理想,因为您会重复抛出异常,直到您的任务完成 -> 不必要的成本我的意见。也许你找到了更好的方法?

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


【解决方案1】:

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

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

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-07-02
    • 2018-04-04
    • 1970-01-01
    • 1970-01-01
    • 2022-01-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多