【问题标题】:Recursive AWS Lambda function calls - Best Practice递归 AWS Lambda 函数调用 - 最佳实践
【发布时间】:2022-01-16 20:09:25
【问题描述】:

我的任务是研究基于 AWS Lambda 构建的服务,该服务执行打开和关闭虚拟机的长时间运行任务。请注意,我来自 Azure 团队,所以我不熟悉 AWS 服务的样式或最佳实践。

原始开发人员采用的方法是将整个工作负载发送到一个 Lambda 函数,然后让该函数获取一部分工作负载,然后使用剩余的工作负载递归调用自身,直到所有项目都消失(工作负载 = 0) .

伪代码:

// Assume this gets sent to a HTTP Lambda endpoint as a whole
let workload = [1, 2, 3, 4, 5, 6, 7, 8]

// The Lambda HTTP endpoint
function Lambda(workload) {
    if (!workload.length) {
        return "No more work!"
    }
    const toDo = workload.splice(0, 2) // get first two items
    doWork(toDo)

    // Then... except it builds a new HTTP request with aws sdk
    Lambda(workload) // 3, 4, 5, 6, 7, 8, etc.
}

这似乎非常低效且不可靠(如果我错了,请纠正我)。在这个过程中存储了很多状态,我认为这会产生很多故障点。

我的计划是建议我们重新设计整个服务以使用 Queue/Worker 类型的框架,理想情况下,端点一次处理一个工作负载,并且是无状态的。

队列将由一个服务填充(Jenkins?Lambda?手动?),然后第二个服务将从队列中读取(理想情况下也可以根据需要横向扩展)。

【问题讨论】:

  • 你是对的,有一个特定的最佳实践。递归实际上是一种不好的做法:docs.aws.amazon.com/lambda/latest/dg/best-practices.html 大多数人倾向于使用 SNS 或 Step Functions 或队列服务 SQS,尽管在 AWS Lambda 中有这种用于多次调用的设计模式,我会尝试思考它的名称。

标签: amazon-web-services aws-lambda


【解决方案1】:

更新:AWS EventBridge 现在看起来像是首选解决方案。


我想到的是“耦合”,请看这里:https://www.jeffersonfrank.com/insights/aws-lambda-design-considerations

联轴器
耦合超越了 Lambda 设计考虑——它更多地是关于整个系统。微服务中的 Lambda 有时是紧密耦合的,但只要在微服务的小黑匣子中的 Lambda 之间传递的数据不是过纯的 HTTP 并且不是同步的,这没什么好担心的。

Lambda 不应该以请求响应的方式直接相互耦合,而是异步耦合。考虑 S3 事件调用 Lambda 函数的场景,然后该 Lambda 还需要调用同一微服务中的另一个 Lambda,依此类推。

aws lambda 耦合

您可能很想实现直接耦合,例如允许 Lambda 1 使用 AWS 开发工具包调用 Lambda 2 等等。这引入了以下一些问题:

  1. 如果 Lambda 1 正在同步调用 Lambda 2,则需要等待后者先完成。 Lambda 1 可能不知道 Lambda 2 也同步调用了 Lambda 3,而 Lambda 1 现在可能需要等待 Lambda 2 和 3 都成功完成。 Lambda 1 可能会超时,因为它需要先等待所有 Lambda 完成,而且您还要在等待期间为每个 Lambda 付费。
  1. 如果 Lambda 3 设置了并发限制并且也被其他服务调用,该怎么办? Lambda 2 和 3 之间的调用将失败,直到它再次具有并发性。错误可以一直返回到 Lambda 1,但是 Lambda 1 然后如何处理错误?它必须存储 S3 事件不成功并且需要重播它。

这个过程可以重新设计为事件驱动:lambda 耦合

这不仅解决了直接耦合方法引入的所有问题,而且还提供了在每个 Lambda 发生错误时重放 DLQ 的方法。不会有任何消息丢失或需要外存,需求与处理解耦。

【讨论】:

    【解决方案2】:

    AWS Step Functions 是实现此目的的一种方法。 Step Functions 用于以您想要的任何方式编排多个 Lambda 函数 - 并行执行、顺序执行或两者的混合。如果需要,您还可以设置等待步骤、条件检查和重试。

    您的整体 step 函数可能看起来像这样(假设您希望 1、2、3 并行执行。然后当所有这些完成后,您希望执行 4,然后再次并行执行 5 和 6)

    配置它也很简单。它接受如下 JSON 格式

    {
      "Comment": "An example of the Amazon States Language using a parallel state to execute two branches at the same time.",
      "StartAt": "Parallel",
      "States": {
        "Parallel": {
          "Type": "Parallel",
          "Next": "Task4",
          "Branches": [
            {
              "StartAt": "Task1",
              "States": {
                "Task1": {
                  "Type": "Task",
                  "Resource": "arn:aws:lambda:ap-south-1:XXX:function:XXX",
                  "End": true
                }
              }
            },
            {
              "StartAt": "Task2",
              "States": {
                "Task2": {
                  "Type": "Task",
                  "Resource": "arn:aws:lambda:ap-south-1:XXX:function:XXX",
                  "End": true
                }
              }
            },
            {
              "StartAt": "Task3",
              "States": {
                "Task3": {
                  "Type": "Task",
                  "Resource": "arn:aws:lambda:ap-south-1:XXX:function:XXX",
                  "End": true
                }
              }
            }
          ]
        },
        "Task4": {
          "Type": "Task",
          "Resource": "arn:aws:lambda:ap-south-1:XXX:function:XXX",
          "Next": "Parallel2"
        },
        "Parallel2": {
          "Type": "Parallel",
          "Next": "Final State",
          "Branches": [
            {
              "StartAt": "Task5",
              "States": {
                "Task5": {
                  "Type": "Task",
                  "Resource": "arn:aws:lambda:ap-south-1:XXX:function:XXX",
                  "End": true
                }
              }
            },
            {
              "StartAt": "Task6",
              "States": {
                "Task6": {
                  "Type": "Task",
                  "Resource": "arn:aws:lambda:ap-south-1:XXX:function:XXX",
                  "End": true
                }
              }
            }
          ]
        },
        "Final State": {
          "Type": "Pass",
          "End": true
        }
      }
    }
    

    【讨论】:

    • 谢谢!会将此视为潜在的解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-12-20
    • 2011-02-13
    • 2017-10-28
    • 1970-01-01
    • 2022-11-30
    • 2021-01-17
    • 1970-01-01
    相关资源
    最近更新 更多