如何通过API网关使用事件调用类型调用Lambda函数?

时间:2015-12-15 16:40:34

标签: python amazon-web-services aws-lambda

文档说:

  

默认情况下,Invoke API采用RequestResponse调用类型。您可以选择通过将Event指定为InvocationType来请求异步执行。

所以我可以发送到我的函数(python)的是InvocationType:各处的事件:

curl -X POST "https://X.execute-api.us-east-1.amazonaws.com/prod/Y?InvocationType=Event" 
-d "InvocationType:Event" 
-H "X-Amz-Invocation-Type:Event"

(function sleeps 3 seconds then responses)

null

但不是异步......文档也说:

  

当您通过AWS控制台或使用Amazon API Gateway通过HTTPS调用Lambda函数时,Lambda始终使用RequestResponse调用类型。

我知道可以通过aws-CLI实现,如果可以从API网关端点进行操作,我不明白。

4 个答案:

答案 0 :(得分:11)

创建两个Lambdas,并在第一次使用Lambda.Client.invoke时使用InvocationType = Event处理Lambda的专用ApiGateway请求。第二个执行您希望ApiGateway请求异步调用的逻辑。

示例专用ApiGateway Lambda处理程序:

from __future__ import print_function

import boto3
import json

def lambda_handler(event, context):
    response = client.invoke(
        FunctionName='<your_long_task_running_function_executer>',
        InvocationType='Event',
        Payload=json.dumps(event)
    )
    return { "result": "OK" }

您可能希望检测到发送请求的失败以及其他类似条件,但由于我并非主要使用python,因此我会将该逻辑留给您。

P.S。请注意,invoke_async已弃用 p.p.s.抱歉,我的帐户是新的,我没有代表将这些添加为评论:0。我借鉴了你的回答; 1.您使用的是弃用的api; 2.你应该(显然很好)将InvocationType = 'Event'添加到你的电话中。

答案 1 :(得分:2)

我意识到API网关只能通过设计调用带有RequestResponse的lambda函数。

但你可以写2个函数:

  1. A&#34;功能接收器&#34;调用&#34; Function Executer&#34;

    的异步调用
    from __future__ import print_function
    
    import boto3
    import json
    
    def lambda_handler(event, context):
        client = boto3.client('lambda')
        client.invoke_async(
            FunctionName='my_long_task_running_function_executer',
            InvokeArgs=json.dumps(event)
        )
        return {"result": "OK"}
    
    1. A&#34;功能执行者&#34;执行长时间运行的任务。
    2. 然后您将拥有一个可以从API网关开始并以InvocationType = Event执行它的进程。

答案 2 :(得分:0)

根据本文,您可以传递标题:X-Amz-Invocation-Type:事件 https://docs.aws.amazon.com/apigateway/latest/developerguide/integrating-api-with-aws-services-lambda.html

答案 3 :(得分:0)

我知道您为什么要这样做,但这不是正确的解决方案。

无论你做什么,不要使用两个 lambda 函数。

您无法控制 lambda 的调用方式,异步或同步。 lambda 的调用者决定了这一点。对于 APIGW,它决定调用 lambda 同步。

可能的解决方案是以下之一:

  • SQS
  • 阶跃函数 (SF)
  • 社交网络

在您的 API 中,您调用这些服务之一,获得成功,然后立即向调用者返回 202。

如果您有大量的单或双动作执行,请使用 SQS。如果您可能长时间运行复杂的状态逻辑,请使用 SF。如果您出于某种原因想忽略我的建议,请使用 SNS。

这些中的每一个都可以(并且应该)回调到 lambda。如果您需要运行超过 15 分钟,他们可以回调 CodeBuild。忽略服务名称,它只是一个支持长达 8 小时运行的 lambda。


现在,为什么不使用两个 lambdas (L1, L2)?答案很简单。一旦您响应您的异步调用已排队(SQS、SF、SNS),您的用户 (202)。他们会期望它 100% 有效。但是如果 L2 lambda 失败会发生什么。它不会重试,也不会继续,你可能永远不会知道。

那个 L2 lambda 的处理程序不再存在,所以你不再知道状态。此外,您可以尝试使用包装器 try/catch 将日志记录添加到 L2,但可能会发生许多其他类型的故障。即使你有那个,CloudWatch 宕机了,你会得到日志吗?可能不是,它只是不是一个可靠的策略。当然,如果你正在做一些你不关心的事情,你可以构建这个架构,但这不是真正的生产解决方案的构建方式。你想要一个可靠的过程。您希望相信接力棒已成功传递给另一个负责完成用户交易的服务。这就是为什么您要使用以下三种服务之一:SQS、SF、SNS。