首页 > 解决方案 > 与 SQS 串在一起的多个 lambda 不传递到目的地

问题描述

我们有一系列 lambda 函数和一系列 SQS 队列。基本上它看起来像这样:

Lambda(foo) => Queue(Alpha) => Lambda(bar) => Queue(Beta) => Lambda(baz)

在这种情况下,Queue(Alpha) 是 Lambda(foo) 的目的地和 Lambda(bar) 的事件源。

我们期望 Lambda(foo) 成功执行,然后将消息传递给 Queue(Alpha),它会触发 Lambda(bar)。然后,如果 Lambda(bar) 成功,它将向 Queue(Beta) 传递一条消息,从而触发 Lambda(baz)。

实际上,调用 Lambda(foo) 会向 Queue(Alpha) 发送消息,后者会触发 Lambda(bar);但随后处理停止。我们检查了日志,一切都成功了,但是没有消息发送到 Queue(beta)。为了排除权限问题,我们直接调用了 Lambda(bar),它确实向 Queue(beta) 发送了一条消息,并按照我们的希望调用了 Lambda(baz)。

所有目标连接都设置为异步。我们一直在运行的测试调用是这样完成的(例如命名可以忽略那里的细节):

aws2 lambda invoke --function-name Queue(foo) --invocation-type Event --payload '{ \"input\": \"jphenow\" }' response.json

有谁知道我们在这里可能缺少什么?在设置的那一刻,这些都是执行的异步 nodejs 函数,context.callbackWaitsForEmptyEventLoop = false;但它们很快就会混合各种不同的语言。

显式调用 SQS 也不是不可能的,尽管对于我们架构的至少一部分来说不是可取的。

任何帮助或线索将不胜感激!

--

值得注意的是,我找到了这篇文章,但他们在第一个目的地工作时遇到了问题,而不是随后的队列。我的直觉说这是一个类似的问题,但我不知道我将如何进一步控制它。

标签: amazon-web-servicesaws-lambda

解决方案


你和@JasonWadsworth 的结论是绝对正确的。这实际上很简单。

  • 根据文档,同步调用由 SQS 消息事件“触发”的 Lambda 函数:

Lambda 轮询队列并使用包含队列消息的事件同步调用您的函数。

  • Destinations 仅在异步调用 lambda 函数时才有效,正如您的链接中提到的那样:

... 用于异步调用的 AWS Lambda 目标。

(虽然它没有明确声明不支持同步调用,但快速谷歌会从其他来源验证这一点。)

  • 您从 CLI异步调用了您的函数。

--invocation-type Event

根据文档

要异步调用函数,请将 InvocationType 设置为 Event。

因此发生的事情是:

  1. Lambda(foo)被异步调用。因为调用是异步的,
  2. 函数结果被写入Queue(Alpha). 因为您已Lambda(bar)在此队列上设置为 lambda 触发器,并且因为 Lambda 基于 SQS 消息同步调用函数,
  3. Lambda(bar)被同步调用。因为它是同步调用的,
  4. Queue(Beta)没有写入,管道停在那里。

我们有一个非常相似的带有 lambda 函数和队列的管道,唯一的区别是我们的函数使用 SQS sdk 写入管道中的下一个队列。不确定这是否是最好的方法,但它肯定是一种方法。


推荐阅读