AWS Lambda函数编排

5

背景

我有一个API网关端点,代理到一个Lambda函数(Lambda A),用于为我的React应用程序获取客户数据。

这个lambda函数发出API调用以获取客户数据,但响应格式有很多不足之处。因此,我想重新格式化它。

我没有将此重新格式化的逻辑放入Lambda A中,而是编写了另一个Lambda函数(Lambda B)。当我的API网关端点被触发时,我需要同时调用这两个函数,并且第一个函数的输出是第二个函数的输入。

首先想到的: 步骤函数

步骤函数似乎是一个自然的选择,但是在阶段之间传输的数据有效载荷的大小有32kb的限制。我们的客户数据json blob通常超过了这个限制。

我听说的唯一的“最佳实践”是将有效负载写入S3,并只将对象键传递给下一个阶段。

这没什么问题,但我不太喜欢必须要写和删除那么多短暂存在的S3对象。每天可能会有几十万或数百万个这样的请求。 所以我放弃了步骤函数的方法(目前)。

当前方案

我目前正在使用JavaScript SDK直接从Lambda A调用Lambda B。这有相当大的缺点,特别是我有时同时运行两个lambda而没有性能好处。换句话说,我为了等待Lambda B的响应(我也在支付)而支付Lambda A的费用。

感觉像一种反模式,并且我听说过它被描述为这样的。

问题

这似乎是一个相对常见的情况 - 发出API调用(函数A),然后执行一些额外的逻辑以补充,重新格式化或以其他方式修改该响应(函数B),然后将其传回给调用者。

我肯定不是第一个想要使用两个Lambda函数来做这样事情的人。

  • 如果不能使用步骤函数,我如何使用两个Lambda函数来完成这个任务?

  • 除了使用S3之外,有没有其他方法来解决步骤函数32kb有效负载大小限制的问题?

  • 如果我愚蠢地想要避免S3 /步骤函数方法,那么说明为什么我担心是无关紧要的答案也会受到欢迎。

编辑

为什么你甚至考虑将获取数据和处理数据的功能拆分为两个不同的AWS Lambda函数?

想象一下,除了Lambda A之外,我还有另外两打需要使用Lambda B功能的lambda。

因此,我将Lambda B的功能打包起来,并将其发布到Nexus中,我的其他两打Lambda都在构建时使用它。所有的Lambda都会因此变得更加臃肿,而且随着我积累越来越多的“Lambda B”,我不得不发布更多的npm包。这正是我想要避免的。

我希望我的“Lambda A”能够消费其他lambda,而不是npm包,以实现广泛共享的功能。也许我过于字面地理解了“lambda function”中的“函数”,或者我只是试图充分利用FaaS的潜力。


1
你的需求是否需要同步响应请求?我在想如果使用 Step Functions,它会如何工作,除非你从 AWS Lambda 函数内部触发 Step Function,这将导致触发 AWS Lambda 函数的相同缺点。 - Dunedan
是的,从同步的角度来看,Lambda B 无法启动直到 Lambda A 完成,并且调用方需要 Lambda B 计算的结果。不需要 lambda 触发步函数;API 网关可以直接完成此操作。步函数会依次执行这两个 lambda,将 Lambda B 的结果返回给调用方。 - Mike Patrick
1
当通过API Gateway触发步骤函数时,您只会在响应中获得执行的ARN而不是步骤函数的结果吗?至少这是https://docs.aws.amazon.com/step-functions/latest/dg/tutorial-api-gateway.html所建议的。 - Dunedan
@Dunedan 很棒的评论 - 你说得完全正确。步骤函数对我的用例不起作用,不是因为任何数据限制,而是因为它们的异步性质。这些解决方法中没有一个很有吸引力。对于未来的读者,这篇关于步骤函数的文章很好地解释了我希望从步骤函数中获得的东西。再次感谢您宝贵的意见。 - Mike Patrick
2个回答

3
从你的问题中,我可以看出以下的需求:
  • 你需要一个AWS Lambda函数(在API Gateway后面),作为客户端应用程序的API端点
  • 你的AWS Lambda函数必须从后端系统获取数据并处理它以供客户端应用程序使用
  • 这些请求是同步的,回答得越快越好(当然也更便宜)
  • 你需要运行的逻辑不太复杂,可能只需要几毫秒就能执行完
为什么你要考虑将获取数据和处理数据的功能拆分成两个不同的AWS Lambda函数呢?不要过于字面地理解“AWS Lambda函数”中的“函数”:你在AWS Lambda函数中运行的代码可以如何复杂都可以。只需在单个AWS Lambda函数中运行所有内容,并在逻辑上将代码拆分即可。这是最有效和清晰的方式。

这是合理的输入,我很感激。将这两个函数合并成一个肯定是我考虑的第一件事情,我可能最终会采取这种方式。然而,我相信我有充分的理由来探索保持它们分开的选择,这就是我在这个问题中试图做的。尽管如此,“此答案有用”还是要点赞的。 - Mike Patrick

0

您没有说明进程A和B之间的有效载荷有多大。但如果它小于250Kb,我建议设置一个中间的SQS队列,让进程A发布结果并且进程B通过队列中的新消息被触发。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接