AWS lambda 调用不调用另一个 lambda 函数 - Node.js

AWS lambda invoke not calling another lambda function - Node.js

赋予所有函数调用权限后。我的 Lambda 函数无法调用另一个函数。每次我超时都有 30 seconds timeout 问题。看起来 lambda 无法获得另一个 lambda 函数

我的 lambda 位于相同的区域、相同的策略、相同的安全组.. 两个 lambda 中的 VPC 也相同。现在唯一不同的是 lambda 函数

以下是角色权限

1) 创建了 AWSLambdaExecuteAWSLambdaBasicExecutionRole

2) 创建了一个要调用的 lambda 函数 Lambda_TEST

exports.handler = function(event, context) {
  console.log('Lambda TEST Received event:', JSON.stringify(event, null, 2));
  context.succeed(event);
};

3) 这是调用它的另一个函数。

var AWS = require('aws-sdk');
AWS.config.region = 'us-east-1';
var lambda = new AWS.Lambda();

exports.handler = function(event, context) {
 var params = {
   FunctionName: 'Lambda_TEST', // the lambda function we are going to invoke
   InvocationType: 'RequestResponse',
   LogType: 'Tail',
   Payload: '{ "name" : "Arpit" }'
 };

  lambda.invoke(params, function(err, data) {
   if (err) {
    context.fail(err);
   } else {
   context.succeed('Lambda_TEST said '+ data.Payload);
  }
 })
};

引用自:

备注

我将用 executor 表示执行第二个 lambdalambda


为什么超时?

由于 执行者 "locked" 在 VPC 后面 - 所有互联网通信都被阻止。

这会导致任何 http(s) 调用超时,因为它们请求数据包永远不会到达目的地。

这就是 aws-sdk 执行的所有操作都会导致超时的原因。


简单的解决方案

如果 执行者 没有 VPC 中 - 把它去掉,一个 lambda 可以在没有 VPC 的情况下工作。

lambda 调用 VPC 中的资源时,需要在 VPC 中定位 lambda

真正的解决方案

从上面说的可以看出,位于 VPC 内的任何资源都无法访问互联网 - 这是不正确的 - 只需进行一些配置.

  1. 创建 VPC.
  2. 创建 2 子网,让一个表示为 private,第二个表示为 public(前面解释了这些术语,请继续阅读)。
  3. 创建一个 Internet 网关 - 这是一个将 VPC 连接到 Internet 的虚拟路由器。
  4. 创建一个 NAT 网关 - 选择 public 子网并为其创建一个新的 elastic IP (此 IP 是您 VPC 的本地 IP)- 此组件将通过管道将通信传送至 internet-gateway.
  5. 创建 2 个 路由表 - 一个名为 public,第二个 私人.

    1. public 路由 table 中,转到 Routes 并添加新路由:

    Destination: 0.0.0.0/0

    Target: the ID of the internet-gateway

    1. private 路由 table 中,转到 Routes 并添加新路由:

    Destination: 0.0.0.0/0

    Target: the ID of the nat-gateway

    • A private 子网是在其路由 table 中的子网 - 没有 路由internet-gateway.

    • A public 子网是在其路由 table 中的子网 - 存在 通往 internet-gateway

    • 的路线

我们这里有什么?

我们创建了这样的东西:

这,是什么允许 private 子网中的资源调用互联网。 您可以找到更多文档 here.

我遇到过同样的问题,即 "pinned" 到 VPC 的 Lambda 无法调用其他 Lambda。我一直在通过重构我的解决方案的结构来处理这个问题,而不使用 NAT。

假设我有几个 lambdas,A、B、C、D...,我希望这些 Lambdas 每个都具有对 RDS 数据库的查询访问权限。为了获得此数据库访问权限,我需要将 lambda 表达式放在与数据库相同的 VPC 中。但我也希望 A、B、C、D... 中的各种 lambda 相互调用。所以我 运行 进入了 Arpit 描述的问题。

我一直在通过将每个 Lambda 拆分为两个 Lambda 来处理这个问题:一个专注于流程(即调用其他 Lambda 并被另一个 Lambda 调用);另一个专注于做 "real" 工作,比如查询数据库。所以我现在有函数 A_flow、B_flow、C_flow、D_flow、...;和函数 A_worker、B_worker、C_worker、D_worker、... 各种流 lambda 不是针对特定 VPC 的 "pinned",因此可以调用其他拉姆达。各种 worker Lambda 与数据库在同一个 VPC 中,可以查询数据库。

每个flow lambda "delegates"将与DB交互的工作交给对应的worker lambda。它通过执行 worker lambda 的同步调用来完成此委托。工作者 lambda 不调用任何其他 lambda。 (在过程流图中,worker lambda 是终端节点。)在我自己的系统中,其他流 lambda 对流 lambda 的调用通常是异步的;但我想如果需要的话它们可以是同步的。

尽管我将这种方法设计为一种变通方法,但它有一个很好的特性,可以将高级功能设计清楚地分为 (a) 流程和 (b) 执行更详细的工作,包括与数据库资源的交互。

截至 2020 年 10 月,AWS PrivateLink 是一种比配置 internet-gateway/NAT-gateway 更简单的解决方案。请参阅此处的发行说明,以及其中指向 PrivateLink 文档的链接:https://aws.amazon.com/blogs/aws/new-use-aws-privatelink-to-access-aws-lambda-over-private-aws-network/

请注意,如果两个 lambda 位于不同的 VPC 中,并且正在执行的 lambda 需要处理来自目标 lambda 的响应,那么两个 lambda 都需要一个端点。