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

我到处都可以想到的地方-但是看不到如何链接或调用函数...肯定存在!

评论

我要到达这里,但是为什么您不能在第一个Lambda函数中依赖AWS JavaScript SDK,创建一个AWS.Lambda客户端并调用第二个函数?

这就是我要尝试的方法-但我不确定要怎么做,因为没有其他Lambda函数执行此操作的示例。

显然,您也可以通过HTTP调用Lambda函数。

还有一个想法,您可以通过SNS将它们链接起来,这可能是我作为一种更具扩展性的策略所采用的方式

此处未提及的另一个常见替代方法是“步函数”或“ SWF”。

#1 楼

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

评论


使用SNS可能是更好的方法,但这是正确的答案。

–银
15年7月31日在20:15

我可能是错的,但是我认为由于调用是同步的,因此第一个Lambda等待第二个Lambda终止,因此您将在两个Lambda运行时产生费用。使用SNS,第一个lambda应该终止并允许第二个lambda独立执行。

– dev
16年1月9日,19:50

多亏了InvocationType:'Event'参数(在FunctionName和Payload之后添加),我能够使它正常工作。从文档中:“您可以选择将Event指定为InvocationType来请求异步执行。”使用异步执行时,将可靠地调用回调函数,而不必等待调用的lambda完成执行。

–亚历山德罗
16年5月23日在15:56



请注意,调用lambda函数的角色需要包括IAM策略AWSLambdaRole。或者,您可以将以下语句对象添加到角色的现有策略中:'{“ Effect”:“ Allow”,“ Action”:[“ lambda:InvokeFunction”],“ Resource”:[“ *”]}`

–鲍勃·阿罗夫(Bob Arlof)
17年2月1日在22:23



实际上,AWS发布了StepFunctions,它使您可以调用多个lambda,而不必从另一个lambda调用lambda,因此。第一个不“等待”第二个完成

– Sebastien H.
18年8月30日在8:02

#2 楼

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

您的第一个Lambda将消息发布到您的SNS Topic,第二个Lambda订阅了该主题。消息到达主题后,第二个Lambda将作为消息的输入参数执行。

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

您也可以使用通过SNS调用跨帐户Lambda函数的这种方法。

评论


Kinesis可能要复杂一些,但是如果您正在寻找更强大的解决方案,那么它可能是您的理想选择。而且,SNS不会存储传入的事件,Kinesis会存储。

– Kixorz
16年6月27日在18:04

“您应该通过SNS链接Lambda函数” –您可以通过证据/文档链接来支持此功能吗?我了解这两种方法如何工作,我希望看到一些意见/明确的陈述,其中哪一种是首选的

–克劳德
16年11月13日在9:33

如果您需要异步的话,这是一个好主意。但是,如果您的第一个lambda函数需要从第二个lambda返回的值,则必须链接lambda,并让第一个lambda函数直接调用第二个lambda函数。

– Noel Llevares
16 Dec 7'在4:23

我不建议使用SNS。您可以仅将异步调用API用于lambda函数,除非您想通知多个订阅者并且不仅仅触发另一个lambda函数,否则无需使用SNS。

–user3807087
17-3-14在16:42



请记住,SNS没有传递保证,因此您可能会触发该消息,但可能不会到达。

–巴特·范·雷莫雷特(Bart Van Remortele)
17年4月26日在13:58

#3 楼

这是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": "*"
    }


评论


该文档似乎建议有效负载必须为JSON。是否可以发送二进制数据?

–mbatchkarov
17年7月25日在19:22

我也喜欢这种方法,但是有一个小故障。您需要将datetime.now()转换为字符串(或以某种方式处理)。否则,您将得到错误datetime.datetime(2017、9、11、14、40、53、23834)不可序列化JSON

– John C
17年9月11日14:43在

在第一个lambda的角色中是否可能更具限制性?即,将其绑定到调用特定功能,而不是所有功能?

–菲尔
18年1月29日在22:42

@Phil也许可以将“ Resource”字段设置为仅允许特定的一组功能,但是我不确定

–蓝皮
18年1月30日在3:24

InvocationType应该为:RequestResponse。要获取您尝试调用的lambda的响应。

– ambigus9
19/09/10在19:03



#4 楼

自从提出此问题以来,Amazon已发布了Step Functions(https://aws.amazon.com/step-functions/)。

AWS Lambda背后的核心原则之一是,您可以将更多精力放在业务逻辑上,而不是将它们联系在一起的应用程序逻辑上。逐步函数使您能够协调函数之间的复杂交互,而无需编写代码即可实现。

#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


评论


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

– Trilok Nagvenkar
18年11月21日9:00

#6 楼

我一直在考虑淘汰SNS,直到在Lambda客户端文档(Java版本)中看到它为止:


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


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

评论


InvocationType ='Event'使它异步。 docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS / ...

– Ankit
17年1月20日在20:05

@Ankit应该是选择的答案,我被误认为使用SNS是执行异步调用的唯一方法,因为没有人回答此信息。

–user3807087
17 Mar 14 '17在16:43

@Ankit您是否知道使用InvocationType ='Event'的示例,但是使用Java而不是JavaScript的示例?有大量的Java文档,但示例却不如JavaScript

–Talador12
18年2月26日在21:16

SNS仍会增加使用成本

– Sebastien H.
18年8月30日在8:04

@SebastienH。 SNS调用Lambda无需花费任何费用。 aws.amazon.com/sns/pricing

–fabdouglas
19年11月26日在14:06

#7 楼

亚马逊于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
    }
  }
}


步骤功能使其真正成为易于编写多个lambda函数并按顺序或并行运行。
您可以在此处获取有关lambda步骤函数的更多信息:
步骤函数

#8 楼

在Java中,我们可以执行以下操作:

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

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

InvokeResult invokeResult = awsLambdaAsync.invoke(invokeRequest); 


此处,有效负载是您的字符串化Java对象,需要将它作为Json对象传递给另一个lambda,以防您需要将一些信息从调用lambda传递给被调用lambda。

#9 楼

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

#10 楼

您也许可以使用Async.js Waterfall功能-例如,请参阅本文档第3步中大代码块的底部:

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

#11 楼

您可以使用AWSLambdaClient直接调用lambda函数(至少通过Java),如AWS的博客文章中所述。

#12 楼

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

我使数据库为其中的每个插入/更新调用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 /

#13 楼

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

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

#14 楼

一种回旋解决方案,但是当我需要链接它们时,我只是为我的lambda函数调用API端点。这样,您就可以在编码时决定是否希望它们异步。

如果您不想设置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

评论


这似乎比SNS少得多,但是我在使用SNS方面没有太多经验

–布兰登
16年11月14日,1:11

您可以共享从lambda内调用API端点所需的代码吗?

– Glenn
17年8月2日在20:20

@Glenn只是一个ajax请求。标记您需要作为查询参数的参数。请参阅:docs.aws.amazon.com/apigateway/api-reference/…和docs.aws.amazon.com/lambda/latest/dg/…

– Anselm
17年8月3日在15:53

另一个问题是,与调用另一个Lambda函数相比,通过API Gateway相对昂贵。运行100毫秒(最低)的128MB函数的费用为每100万次呼叫0.21美元,而API网关的费用为每100万次呼叫3.50美元。显然,如果您要运行更长的时间或使用更多的内存,则必须乘以21美分,但是,每百万$ 3.50确实很昂贵。 (这些价格自2017年8月起生效)

–朱冠希
17年8月17日在17:57



#15 楼

这是调用另一个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 楼

您可以直接以异步方式直接从其他Lambda函数触发Lambda函数。
https://docs.aws.amazon.com/lambda/latest/dg/invocation-async.html#invocation-async-destinations

#17 楼

有很多答案,但是没有一个强调的是,不建议针对同步调用不建议调用另一个lambda函数,而实际上应该使用的是Step Functions
原因不建议使用该解决方案:

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

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

#18 楼

您可以设置AWS_REGION环境。

assert(process.env.AWS_REGION, 'Missing AWS_REGION env (eg. ap-northeast-1)');
const aws = require('aws-sdk');
const lambda = new aws.Lambda();