AWS Lambda函数可以调用另一个吗?

Sil*_*ver 280 amazon-web-services node.js aws-lambda aws-api-gateway

我有2个Lambda函数 - 一个产生报价,一个将报价转换为订单.我希望Order lambda函数调用Quote函数来重新生成引用,而不是仅从不受信任的客户端接收它.

我看到了我能想到的所有地方 - 但看不出我是如何进行链接或调用功能的......当然这存在!

Nic*_*nié 333

我找到了一种方法aws-sdk.

var aws = require('aws-sdk');
var lambda = new aws.Lambda({
  region: 'us-west-2' //change to your region
});

lambda.invoke({
  FunctionName: 'name_of_your_lambda_function',
  Payload: JSON.stringify(event, null, 2) // pass params
}, function(error, data) {
  if (error) {
    context.done('error', error);
  }
  if(data.Payload){
   context.succeed(data.Payload)
  }
});
Run Code Online (Sandbox Code Playgroud)

您可以在此处找到该文档:http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Lambda.html

  • 由于`InvocationType:'Event'`参数(在`FunctionName`和`Payload`之后添加),我能够让它工作.从文档:_"您可以选择通过将Event指定为InvocationType来请求异步执行."_使用异步执行,将可靠地调用回调函数,但无需等待调用的lambda完成执行. (72认同)
  • 使用SNS可能是更好的方法,但这是正确的答案. (26认同)
  • 我可能是错的,但我认为因为调用是同步的,第一个lambda等待第二个lambda终止,因此当两个lambda运行时你将产生费用.使用SNS,第一个lambda应终止并允许第二个lambda独立执行. (25认同)
  • 请注意,调用lambda函数的角色需要包含IAM策略`AWSLambdaRole`.或者,您可以将以下语句对象添加到角色的现有策略中:'{"Effect":"Allow","Action":["lambda:InvokeFunction"],"Resource":["*"]}` (24认同)
  • 实际上,AWS发布了StepFunctions,它使您可以调用多个Lambda,而不必从另一个Lambda调用Lambda,因此。第一个不“等待”第二个完成 (2认同)

kix*_*orz 103

你应该链接你的Lambda functions通道SNS.此方法以最小的工作量提供了良好的性能,延迟和可伸缩性.

您首先Lambda向您发布消息,SNS Topic第二个Lambda订阅此主题.一旦消息到达主题,第二个Lambda消息就作为输入参数执行.

请参阅使用Amazon SNS通知调用Lambda函数.

您还可以使用此方法通过SNS调用跨帐户Lambda函数.

  • 如果您需要它是异步的,这是一个好主意.但是如果你的第一个lambda函数*需要*来自第二个lambda的返回值,你必须链接lambdas并让第一个lambda函数直接调用第二个lambda函数. (25认同)
  • 我不建议使用 SNS。您可以将异步调用 API 用于 lambda 函数——没有理由使用 SNS,除非您想通知多个订阅者而不只是触发另一个 lambda 函数。 (8认同)
  • "你应该通过SNS链接你的Lambda函数" - 你能用证据/链接到文档来支持吗?我看到两种方法是如何工作的,我有兴趣看到一些意见/明确的陈述,哪一个是首选的 (7认同)
  • 请记住,SNS没有交付保证,因此您可能会触发消息,但可能无法到达. (4认同)
  • 为了解决交付保证问题,您可以通知SQS队列并使用重试模式来确保成功处理数据。https://aws.amazon.com/sqs/faqs/ (3认同)
  • Kinesis 可能有点复杂,但如果您正在寻找更强大的解决方案,那么它可能是您的不错选择。此外,SNS 不存储传入事件,而 Kinesis 存储。 (2认同)
  • 使用此方案还会增加 SNS 使用成本,在我看来这不是最佳实践 (2认同)

blu*_*kin 63

这是python的示例代码,

from boto3 import client as boto3_client
from datetime import datetime
import json

lambda_client = boto3_client('lambda')

def lambda_handler(event, context):
    msg = {"key":"new_invocation", "at": datetime.now()}
    invoke_response = lambda_client.invoke(FunctionName="another_lambda_",
                                           InvocationType='Event',
                                           Payload=json.dumps(msg))
    print(invoke_response)
Run Code Online (Sandbox Code Playgroud)

顺便说一句,你需要在你的lambda角色中添加这样的策略

   {
        "Sid": "Stmt1234567890",
        "Effect": "Allow",
        "Action": [
            "lambda:InvokeFunction"
        ],
        "Resource": "*"
    }
Run Code Online (Sandbox Code Playgroud)

  • 我也更喜欢这种方法,但它有一个小故障。您需要将 `datetime.now()` 转换为字符串(或以某种方式处理它)。否则,您会收到错误 `datetime.datetime(2017, 9, 11, 14, 40, 53, 23834) is not JSON serializable` (3认同)
  • `IncationType` 应该是:`RequestResponse`。从您尝试调用的 lambda 获取响应。 (2认同)

dus*_*noe 26

自从提出这个问题以来,亚马逊已经发布了步骤功能(https://aws.amazon.com/step-functions/).

AWS Lambda背后的核心原则之一是,您可以更多地关注业务逻辑,而不是关注将它们联系在一起的应用程序逻辑.步骤函数允许您协调函数之间的复杂交互,而无需编写代码来执行此操作.


Ben*_*den 10

我一直在寻找切断SNS,直到我在Lambda客户端文档(Java版本)中看到它:

访问AWS Lambda的客户端.使用此客户端进行的所有服务调用都是阻止的,并且在服务调用完成之前不会返回.

所以SNS有一个明显的优势:它是异步的.你的lambda不会等待随后的lambda完成.

  • InvocationType ='Event'使其异步.http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Lambda.html#invoke-property (17认同)
  • @Ankit应该是选定的答案,我被误导相信使用SNS是进行异步调用的唯一方法,因为没有人回答这些信息. (3认同)

Bla*_*ack 10

有很多答案,但没有一个答案强调调用另一个 lambda 函数不是同步调用的推荐解决方案,您应该使用的实际上是Step Functions

不推荐解决方案的原因:

  • 当两个功能互相等待时,您就需要为它们付费
  • 你的代码负责重试

您还可以将它用于相当复杂的逻辑,例如并行步骤和捕获失败。每次执行也会被注销,这使得调试更加简单。


Tri*_*kar 9

此解决方案使用boto3和Python完成:

import boto3
import json

invokeLambda = boto3.client('lambda', region_name='eu-west-1')

def lambda_handler(event, context):
    invokeLambda.invoke(FunctionName = 'function_name', InvocationType = 'RequestResponse', Payload = json.dumps(event))

    return True
Run Code Online (Sandbox Code Playgroud)

  • InvocationType从以下选项中选择。RequestResponse(默认)-同步调用该函数。保持连接打开,直到函数返回响应或超时。事件-异步调用该函数。将多次失败的事件发送到函数的死信队列(如果已配置)。DryRun-验证参数值并验证用户或角色是否有权调用该函数。 (2认同)

Sun*_*pil 8

亚马逊于2016年在AWS lambda中引入了步骤功能。我认为,现在使用步骤功能更加方便,因为它非常容易使用。您可以使用以下两个lambda函数构建状态机:

  • 产生报价
  • 把报价变成订单

您可以轻松地做到这一点,如下所示:

在这里,您可以让第一个状态产生一个报价,而另一个状态变成顺序

{
  Comment: "Produce a quote and turns into an order",
  StartAt: "ProduceQuote",
  States: {
    ProduceQuote: {
      "Type": Task,
      "Resource": "arn:aws:lambda:us-east-1:123456789012:function:ProduceQuote",
      "next": TurnsToOrder
    }
    TurnsToOrder: {
      Type: Task,
      Resource: "arn:aws:lambda:us-east-1:123456789012:function:ProduceQuote",
      end: true
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

Steps函数使编写多个lambda函数并依次或并行运行变得非常容易。您可以在此处获取有关lambda步骤功能的更多信息: 步骤功能


Suy*_*ash 6

在java中,我们可以这样做:

AWSLambdaAsync awsLambdaAsync = AWSLambdaAsyncClientBuilder.standard().withRegion("us-east-1").build();

InvokeRequest invokeRequest = new InvokeRequest();
invokeRequest.withFunctionName("youLambdaFunctionNameToCall").withPayload(payload);

InvokeResult invokeResult = awsLambdaAsync.invoke(invokeRequest); 
Run Code Online (Sandbox Code Playgroud)

在这里,payload 是字符串化的java 对象,它需要作为 Json 对象传递给另一个 lambda,以防您需要将一些信息从调用 lambda 传递到被调用 lambda。


小智 5

我正在使用blueskin提供的答案,但由于InvocationType ='Event'async,所以无法读取有效负载响应,因此我将其更改为InvocationType ='RequestResponse',现在一切正常。