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

How to invoke Lambda function with Event Invocation Type via API Gateway?

文档说:

By default, the Invoke API assumes RequestResponse invocation type. You can optionally request asynchronous execution by specifying Event as the InvocationType.

所以我可以发送到我的函数 (python) 的所有内容都是 InvocationType:Event:

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

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

When you invoke a Lambda function via the AWS console or over HTTPS using Amazon API Gateway, Lambda always uses the RequestResponse invocation type.

我知道可以通过 aws-CLI 实现,但我不明白是否可以从 API 网关端点实现。

我意识到 API 网关在设计上只使用 RequestResponse 调用 lambda 函数。

但是你可以写两个函数:

  1. A "Function Receiver" 调用对 "Function Executer"

    的异步调用
    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 "Function Executer" 执行长 运行 任务。

然后您将拥有一个可以从 API 网关开始并作为 InvocationType=Event 执行的流程。

创建两个 Lambda,并在第一个中使用 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' 添加到你的调用中。

根据这篇文章你可以传递一个header:X-Amz-Invocation-Type:事件 https://docs.aws.amazon.com/apigateway/latest/developerguide/integrating-api-with-aws-services-lambda.html

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

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

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

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

  • SQS
  • 步进函数(SF)
  • 社交网络

在您的 API 中,您调用其中一项服务,返回成功,然后立即 return 向您的调用者发送 202。

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

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

的 lambda

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

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