如何从另一个触发一个 AWS Lambda 函数,保证第二个只运行一次?
How can I trigger one AWS Lambda function from another, guaranteeing the second only runs once?
我已经使用无服务器框架构建了一些 AWS Lambda 函数管道。目前有五个 steps/functions,我需要它们按顺序 运行 并且每个 运行 恰好一次。大致来说,功能是:
- 通过 HTTP 请求触发函数,用 ID 响应。
- 访问并 API 获取要下载的资源的 URL。
- 下载该资源并将副本上传到 S3。
- 更改该资源并将更改后的副本上传到 S3。
- 将更改后的资源提交给另一个 API。
细节并不重要,但问题是:什么是最好的event/trigger用来沿着这条函数线移动?第一个是由 HTTP 调用触发,但第一个需要以某种方式触发第二个,然后第二个触发第三个,依此类推。
我使用 AWS SNS 编写了所有代码,但现在我已将其部署到暂存区,我看到 SNS often triggers more than once。我可以添加一堆代码来检测这一点,但我宁愿不这样做。而且问题也很复杂——如果第二个函数被触发两次,它会发送两个 SNS 通知来触发第三步。如果这些通知中的任何一个被加倍......最后一个函数可以被调用十次而不是一次并不是不合理的。
那么我最好的选择是什么?通过 HTTP 触发链?运动可能?我从未使用过除 HTTP 或 SNS 之外的触发器,所以我不太确定我的选项是什么,以及哪些选项保证只触发一次函数。
AWS Step Functions 似乎很好地针对了将单独的 AWS 操作绑定到一个具有明确定义的错误处理的连贯工作流的用例。
不确定定价是否适合您(可以 pricey 用于数百万次以上的操作)但它可能值得一看。
也不确定性能开销或其他限制,所以 YMMV。
您可以在完成该步骤中所需的处理后,在您的 lambda 函数中简单地触发下一个 lambda 异步。
因此,第一个 lambda 是由 HTTP 调用触发的,在该 lambda 执行中,完成此步骤后,只需启动下一个 lambda 函数异步,而不是发送通过 SNS 或 Kinesis 触发。在每个步骤中重复此过程。这将保证 lambda 一次性执行所有步骤。
事件性 Lambda 触发器(SNS、S3、CloudWatch 等)通常保证至少调用一次,而不是恰好调用一次。正如您所指出的,您必须手动处理重复数据删除,例如,跟踪 DynamoDB 中的事件 ID(使用 strongly consistent reads!), or by implementing idempotent Lambdas,这意味着即使在使用相同的输入多次调用。在您的示例中,第 4 步本质上是幂等的,前提是该函数除了存储更改后的副本外没有任何副作用,并且新副本会覆盖具有相同事件 ID 的任何先前存储的副本。
SQS FIFO 是一项能够保证开箱即用的服务。不幸的是,此服务不能用于直接触发 Lambda,因此您必须设置计划的 Lambda 以定期轮询 FIFO 队列(根据 )。在您的情况下,您可以通过这种安排处理第 5 步,因为我假设您不想多次向目标 API 提交相同的资源。
总而言之,我将如何处理:
- 通过 HTTP 调用的 Lambda A 以 ID 响应并继续从 API 异步获取资源并将其存储到 S3
- Lambda B,由 S3 上传事件调用,下载上传的资源,对其进行更改,将更改后的副本存储到 S3,最后使用更改后的资源文件名作为不同的重复数据删除 ID 将消息推送到 FIFO SQS 队列中
- Lambda C,由 CloudWatch 调度程序调用,轮询 FIFO SQS 队列,并根据新消息从 S3 获取指定的更改资源并将其提交给另一个 API
采用这种安排,即使同一 S3 上传事件偶尔会执行 Lambda B 两次或更多次,也不会造成任何损害,因为 FIFO SQS 队列会在流到达 Lambda C 之前为您处理重复数据删除。
AWS Step 函数适合您:https://docs.aws.amazon.com/step-functions/latest/dg/welcome.html
您将根据之前的执行输出执行您想要的步骤。
每个task/step只需要在想要的"state".
中正确输出一个json
https://docs.aws.amazon.com/step-functions/latest/dg/concepts-states.html
根据状态,您的工作流程将继续进行。您可以轻松创建工作流程并触发 lambda 或 ECS 任务。
ECS 任务是您自己的 "lambda" 环境,运行ning 不受 AWS Lambda 环境的限制。
使用 ECS 任务,您可以 运行 在裸机上、在您自己的 EC2 计算机上或在 ECS 上的 ECS Docker 容器中,因此具有无限的资源可扩展限制。
与限制非常严格的 Lambda 相比:500Mb 磁盘、执行时间限制等。
我已经使用无服务器框架构建了一些 AWS Lambda 函数管道。目前有五个 steps/functions,我需要它们按顺序 运行 并且每个 运行 恰好一次。大致来说,功能是:
- 通过 HTTP 请求触发函数,用 ID 响应。
- 访问并 API 获取要下载的资源的 URL。
- 下载该资源并将副本上传到 S3。
- 更改该资源并将更改后的副本上传到 S3。
- 将更改后的资源提交给另一个 API。
细节并不重要,但问题是:什么是最好的event/trigger用来沿着这条函数线移动?第一个是由 HTTP 调用触发,但第一个需要以某种方式触发第二个,然后第二个触发第三个,依此类推。
我使用 AWS SNS 编写了所有代码,但现在我已将其部署到暂存区,我看到 SNS often triggers more than once。我可以添加一堆代码来检测这一点,但我宁愿不这样做。而且问题也很复杂——如果第二个函数被触发两次,它会发送两个 SNS 通知来触发第三步。如果这些通知中的任何一个被加倍......最后一个函数可以被调用十次而不是一次并不是不合理的。
那么我最好的选择是什么?通过 HTTP 触发链?运动可能?我从未使用过除 HTTP 或 SNS 之外的触发器,所以我不太确定我的选项是什么,以及哪些选项保证只触发一次函数。
AWS Step Functions 似乎很好地针对了将单独的 AWS 操作绑定到一个具有明确定义的错误处理的连贯工作流的用例。
不确定定价是否适合您(可以 pricey 用于数百万次以上的操作)但它可能值得一看。
也不确定性能开销或其他限制,所以 YMMV。
您可以在完成该步骤中所需的处理后,在您的 lambda 函数中简单地触发下一个 lambda 异步。
因此,第一个 lambda 是由 HTTP 调用触发的,在该 lambda 执行中,完成此步骤后,只需启动下一个 lambda 函数异步,而不是发送通过 SNS 或 Kinesis 触发。在每个步骤中重复此过程。这将保证 lambda 一次性执行所有步骤。
事件性 Lambda 触发器(SNS、S3、CloudWatch 等)通常保证至少调用一次,而不是恰好调用一次。正如您所指出的,您必须手动处理重复数据删除,例如,跟踪 DynamoDB 中的事件 ID(使用 strongly consistent reads!), or by implementing idempotent Lambdas,这意味着即使在使用相同的输入多次调用。在您的示例中,第 4 步本质上是幂等的,前提是该函数除了存储更改后的副本外没有任何副作用,并且新副本会覆盖具有相同事件 ID 的任何先前存储的副本。
SQS FIFO 是一项能够保证开箱即用的服务。不幸的是,此服务不能用于直接触发 Lambda,因此您必须设置计划的 Lambda 以定期轮询 FIFO 队列(根据
总而言之,我将如何处理:
- 通过 HTTP 调用的 Lambda A 以 ID 响应并继续从 API 异步获取资源并将其存储到 S3
- Lambda B,由 S3 上传事件调用,下载上传的资源,对其进行更改,将更改后的副本存储到 S3,最后使用更改后的资源文件名作为不同的重复数据删除 ID 将消息推送到 FIFO SQS 队列中
- Lambda C,由 CloudWatch 调度程序调用,轮询 FIFO SQS 队列,并根据新消息从 S3 获取指定的更改资源并将其提交给另一个 API
采用这种安排,即使同一 S3 上传事件偶尔会执行 Lambda B 两次或更多次,也不会造成任何损害,因为 FIFO SQS 队列会在流到达 Lambda C 之前为您处理重复数据删除。
AWS Step 函数适合您:https://docs.aws.amazon.com/step-functions/latest/dg/welcome.html
您将根据之前的执行输出执行您想要的步骤。 每个task/step只需要在想要的"state".
中正确输出一个jsonhttps://docs.aws.amazon.com/step-functions/latest/dg/concepts-states.html
根据状态,您的工作流程将继续进行。您可以轻松创建工作流程并触发 lambda 或 ECS 任务。 ECS 任务是您自己的 "lambda" 环境,运行ning 不受 AWS Lambda 环境的限制。
使用 ECS 任务,您可以 运行 在裸机上、在您自己的 EC2 计算机上或在 ECS 上的 ECS Docker 容器中,因此具有无限的资源可扩展限制。 与限制非常严格的 Lambda 相比:500Mb 磁盘、执行时间限制等。