【问题标题】:AWS SQS triggering Lambda - How to stop Lambda from taking in more SQS events until a certain task is completeAWS SQS 触发 Lambda - 如何阻止 Lambda 在某个任务完成之前接收更多 SQS 事件
【发布时间】:2022-08-26 03:39:18
【问题描述】:

我有一个触发处理程序 Lambda 的 SQS 队列。此 Lambda 仅接收队列中的消息并执行 Step Functions 状态机,并将消息作为输入。

Lambda 在从 Step Functions 收到状态机开始执行的 HTTP 响应时结束。

状态机的任务之一是并发限制为 1 的 Glue 作业。因此流程如下:

SQS -> Lambda -> 状态机(包含 Glue 作业)

状态机步骤:

  1. 在输入消息中传递一些参数
  2. 使用参数运行 Glue 作业任务
  3. 等。等等

    当 SQS 事件触发 Lambda 时,它会自动从队列中移除。

    期望的结果

    状态机中一次只能运行一个的 Glue 作业任务。所以我希望整个状态机一次只运行一个。我可能需要在 SQS 队列中保留新的传入事件,直到当前状态机运行完成。

    问题

    目前,如果状态机已经在运行,Lambda 将开始第二次执行状态机。

    但是由于有一个 Glue 作业任务仍在运行,并且状态机的第二个实例也尝试运行该作业,因此 Glue 会失败。第二次执行状态机时返回如下错误:

    {
      "resourceType": "glue",
      "resource": "startJobRun.sync",
      "error": "Glue.ConcurrentRunsExceededException",
      "cause": "Concurrent runs exceeded for GLUE_JOB_NAME (Service: AWSGlue; Status Code: 400; Error Code: ConcurrentRunsExceededException; Request ID: 60ea8feb-34a2-46e2-ac17-0152f22371a2; Proxy: null)"
    }
    

    这使得状态机失效,触发 Lambda 启动状态机的 SQS 事件永远丢失;状态机不会再次尝试对该事件采取行动。

    我考虑过的解决方案

    1)

    不是让 SQS 队列在事件进入时触发 Lambda,而是让 Lambda 定时,检查状态机的当前执行。如果没有,它将从队列中获取并启动状态机。

    这可能是最简单的解决方案,但缺点是它会一次将事件留在队列中几分钟,更重要的是,在此之前已经有一个单独的轮询 Lambda,它将事件放入 SQS 队列中,所以有另一个定时 Lambda 是重言式的。

    2)

    Glue 作业的并发性不是我想改变的。

    但是,如果我让 Lambda 轮询 Step Functions 以查看是否有一个状态机实例已经在运行,那么我可以稍后让 Lambda 重试。

    如果我给 Lambda 一个并发 1,那么当 Lambda 函数等待时,SQS 队列不会触发更多的函数实例。队列中的新事件将被阻塞,直到当前状态机执行完成。

    问题是我们在状态机执行的整个过程中都在运行 Lambda,这可能需要很长时间。这使得 Lambda 运行时间和计费时间变得不必要地长。它也可能超过 Lambda 运行时限制。

    3)

    Lambda 可以轮询 Step Functions 以获取当前执行,如果有,它可以返回运行时错误,我相信这会将 SQS 事件放回队列中以便稍后重试。

    但据我所知,SQS 之后会立即触发 Lambda,即使有延迟窗口也是如此。此外,在没有当前执行的情况下,我不想要延迟窗口。


    我想要求比这 3 个更好的解决方案,但如果没有,我会求助于1).

【问题讨论】:

    标签: aws-lambda amazon-sqs aws-step-functions


    【解决方案1】:

    可以使用此设置:

    可以使用 lambda 函数从 sqs 轮询作业,然后触发状态机。 现在应该有两个 lambda 触发器以使其具有故障安全性。

    1. 主要触发器是状态完成时发出的事件 机器。这将解决同步问题。 https://docs.aws.amazon.com/step-functions/latest/dg/cw-events.html
    2. lambda 的时间安排事件。这将确保 lambda 在队列为空后不会错过任何新作业。 (在 lambda 的开头,代码段将检查是否已经有任何状态机正在运行。如果是,则退出)

    【讨论】:

      猜你喜欢
      • 2019-10-09
      • 2020-05-17
      • 2022-07-20
      • 2020-07-28
      • 1970-01-01
      • 2019-05-14
      • 2021-03-28
      • 2018-03-01
      • 2020-10-15
      相关资源
      最近更新 更多