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

时间:2015-07-30 03:35:18

标签: node.js amazon-web-services aws-lambda aws-api-gateway

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

我看到了我能想到的所有地方 - 但无法看到我如何进行链接或调用这些功能......当然这确实存在!

18 个答案:

答案 0 :(得分:281)

我找到了使用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)
  }
});

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

答案 1 :(得分:87)

您应该通过Lambda functions链接SNS。这种方法可以以最小的工作量提供良好的性能,延迟和可扩展性。

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

请参阅Invoking Lambda functions using Amazon SNS notifications

您也可以将此方法用于Invoke cross-account Lambda functions via SNS

答案 2 :(得分:53)

这里是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)

顺便说一下,您需要将这样的策略添加到您的lambda角色

   {
        "Sid": "Stmt1234567890",
        "Effect": "Allow",
        "Action": [
            "lambda:InvokeFunction"
        ],
        "Resource": "*"
    }

答案 3 :(得分:22)

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

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

答案 4 :(得分:9)

我正在考虑削减SNS,直到我在Lambda client docs (Java version)中看到这个:

  

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

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

答案 5 :(得分:5)

此解决方案是使用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

答案 6 :(得分:4)

我正在使用 blueskin 提供的答案,但由于 InvocationType ='事件' 异步,我无法阅读有效负载响应,所以我改为InvocationType ='RequestResponse',现在一切正常。

答案 7 :(得分:3)

Amazon于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
    }
  }
}

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

答案 8 :(得分:2)

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

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

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

InvokeResult invokeResult = awsLambdaAsync.invoke(invokeRequest); 

这里,payload是你的 stringified java对象,需要将其作为Json对象传递给另一个lambda,以防你需要将一些信息从调用lambda传递给被调用的lambda。

答案 9 :(得分:2)

您可以使用Async.js瀑布功能 - 请参阅本文档第3步中大代码块的底部部分,以获取示例:

https://aws.amazon.com/blogs/compute/better-together-amazon-ecs-and-aws-lambda/

答案 10 :(得分:1)

有点迂回的解决方案但我只需要将 API端点称为我的lambda函数,当我需要链接它们时。如果您希望它们是异步的,可以在编码时决定。

如果您不想设置POST请求,您只需设置一对简单的GET请求,或者根本不设置查询字符串参数,以便于事件传递。

- 编辑 -

请参阅:https://docs.aws.amazon.com/apigateway/api-reference/making-http-requests/

和:http://docs.aws.amazon.com/lambda/latest/dg/with-on-demand-https-example.html

答案 11 :(得分:1)

我遇到了同样的问题,但我实现的Lambda函数会在DynamoDB中插入一个条目,所以我的解决方案使用DynamoDB触发器。

我让DB为表中的每个插入/更新调用一个Lambda函数,因此这将分离两个Lambda函数的实现。

文档在这里: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Streams.Lambda.html

以下是导游演练: https://aws.amazon.com/blogs/aws/dynamodb-update-triggers-streams-lambda-cross-region-replication-app/

答案 12 :(得分:1)

您可以使用AWS post中所述的AWSLambdaClient直接调用lambda函数(至少通过Java)。

答案 13 :(得分:1)

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

不推荐解决方案的原因:

  • 您为这两个功能付费
  • 您的代码负责重试

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

答案 14 :(得分:0)

其他人指出要使用SQS和步进功能。但是这两种解决方案都增加了额外的成本。据说阶跃函数状态转换非常昂贵。

AWS lambda提供了一些重试逻辑。尝试3次的地方。当您使用API​​触发它时,我不确定这是否仍然有效。

答案 15 :(得分:0)

这是调用另一个lambda函数并获得其响应的python示例。有两种调用类型'RequestResponse''Event'。如果要获取lambda函数的响应,请使用“ RequestResponse”,并使用“事件”异步调用lambda函数。因此,异步和同步都可用。

    lambda_response = lambda_client.invoke(
                FunctionName = lambda_name,
                InvocationType = 'RequestResponse',
                Payload = json.dumps(input)
                )
    resp_str = lambda_response['Payload'].read()
    response = json.loads(resp_str)

答案 16 :(得分:0)

您可以直接以异步方式直接从其他Lambda函数触发Lambda函数。

https://docs.aws.amazon.com/lambda/latest/dg/invocation-async.html#invocation-async-destinations

答案 17 :(得分:-1)

您可以设置AWS_REGION环境。

<div class="tbl-main">

  <div class="tbl-searchpanel">
    <input id="toggle" type="checkbox" />
    <label for="toggle"></label>
    <div id="expand"></div>
  </div>

  <div class="tbl-container">
  </div>

</div>