如何通过 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 函数。
但是你可以写两个函数:
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"}
- 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。
文档说:
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 函数。
但是你可以写两个函数:
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"}
- 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.
现在,为什么不使用两个 lambdas (L1, L2)?答案很简单。一旦您响应您的异步调用已排队(SQS、SF、SNS)给您的用户 (202)。他们会期望它 100% 有效。但是如果 L2 lambda 失败会发生什么。它不会重试,不会继续,你可能永远不会知道。
L2 lambda 的处理程序已不存在,因此您不再了解状态。此外,您可以尝试使用 wrapper try/catch
将日志记录添加到 L2,但可能会发生许多其他类型的故障。即使你有那个,如果 CloudWatch 宕机了,你会得到日志吗?不可能,这不是一个可靠的策略。当然,如果您正在做一些您不关心的事情,您可以构建这个架构,但这不是构建真正的生产解决方案的方式。您需要一个可靠的过程。您希望相信接力棒已成功传递给另一项服务,该服务负责完成用户的交易。这就是为什么您想使用三种服务之一:SQS、SF、SNS。