我想在API网关调用的lambda函数中执行http请求。问题是,请求需要一些时间才能完成(<20秒),并且不希望客户端等待响应。在我对异步请求的研究中,我了解到我可以传递X-Amz-Invocation-Type:Event
标头以使请求异步执行,但这不起作用,代码仍然“等待”http请求完成。
以下是我的lambda代码:
'use strict';
const https = require('https');
exports.handler = function (event, context, callback) {
let requestUrl;
requestUrl = event.queryStringParameters.url;
https.get(requestUrl, (res) => {
console.log('statusCode:', res.statusCode);
console.log('headers:', res.headers);
res.on('data', (d) => {
process.stdout.write(d);
});
}).on('error', (e) => {
console.error(e);
});
let response = {
"statusCode": 200,
"body": JSON.stringify(event.queryStringParameters)
};
callback(null, response);
};
任何帮助都将不胜感激。
答案 0 :(得分:2)
您可以使用两个Lambda函数。
Lambda 1由API网关触发,然后异步调用Lambda 2(InvocationType
= Event
),然后向用户返回响应。
Lambda 2一旦被调用,就会触发HTTP请求。
答案 1 :(得分:0)
无论你做什么,不要使用两个 lambda 函数。
您无法控制 lambda 的调用方式,异步或同步。 lambda 的调用者决定了这一点。对于 APIGW,它决定调用 lambda 同步。
可能的解决方案是以下之一:
在您的 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。