Aws lambda 建议处理多个lambda调用的方法
主要问题: Lambda函数在成功的外部API调用后未退出,从而触发多个外部API调用 我有一个lambda函数,它在事件发生时侦听空闲事件,调用lambda函数。我使用一些条件检查过滤这些事件,当目标事件发生时,我进行外部API调用 但是,上述所有方法都有效,每个事件都会多次触发外部API调用(如果成功,则触发次数应为1,但触发次数约为4次) 幂等元 -通常人们会把这个问题与幂等性联系起来,但是,考虑到条件块中的外部API调用会被触发更多次,我认为这不是一个问题Aws lambda 建议处理多个lambda调用的方法,aws-lambda,slack,Aws Lambda,Slack,主要问题: Lambda函数在成功的外部API调用后未退出,从而触发多个外部API调用 我有一个lambda函数,它在事件发生时侦听空闲事件,调用lambda函数。我使用一些条件检查过滤这些事件,当目标事件发生时,我进行外部API调用 但是,上述所有方法都有效,每个事件都会多次触发外部API调用(如果成功,则触发次数应为1,但触发次数约为4次) 幂等元 -通常人们会把这个问题与幂等性联系起来,但是,考虑到条件块中的外部API调用会被触发更多次,我认为这不是一个问题 我可以确认条件检查是否正确过
- 我可以确认条件检查是否正确过滤了适当的事件
- 在后续(附加)外部API调用之前,我可以确认我正在接收一个
statusCode 200
- 我已经包括了
和冗余的context.done()
,但运气不好callback()
- 有没有人提出了解决这个问题的建议
- 我读过一些人使用DynamoDB跟踪执行请求,但这听起来不是一个好方法
const axios = require('axios');
const sendMessages = async(event, context, callback) => {
// test the message for a match
if (event.type === 'message' && event.bot_id !== undefined) {
console.log("filter events for specific event");
let URL = 'https://someurl.com/slack/events';
let response = await axios.post(URL, {
events: event,
});
console.log("response success :: ", response.status);
if (response.status === 200) {
console.log("condition met");
context.done();
callback(null, 'successful request');
}
}
callback(null, 'successful request');
};
// Lambda handler
exports.server = (data, context, callback) => {
let eventData = JSON.parse(data.body);
switch (data.path) {
case "/slack-events": sendMessages(eventData.event, context, callback); break;
default: callback(null);
}
};
预期行为
- 在调用和条件检查时进行单个外部API调用;响应后退出。状态===200
async/wait
与context.done
和callback()
调用混淆了
如果您的函数已经是异步的
,那么请始终坚持等待
,忘记上下文
和回调
对象
请注意,sendMessages
是async
,因此它会返回一个承诺,但您不会使用该承诺执行任何操作。你应该等待它。我已经相应地更改了您的代码,并且去掉了上下文
和回调
对象,您不需要它们
const axios = require('axios');
const sendMessages = async (event) => {
// test the message for a match
if (event.type === 'message' && event.bot_id !== undefined) {
console.log('filter events for specific event');
let URL = 'https://someurl.com/slack/events';
let response = await axios.post(URL, {
events: event,
});
console.log('response success :: ', response.status);
return response;
}
return Promise.resolve({});
};
// Lambda handler
exports.server = async (event) => {
let eventData = JSON.parse(event.body);
switch (event.path) {
case '/slack-events':
await sendMessages(eventData.event);
break;
}
return {
message: 'Success',
}
};
如果此Lambda由API网关调用,则需要返回一个2xx状态代码(或在出现错误时返回4xx和5xx)和一个字符串化的主体,以便它可以正确终止,如下所示:
return {
statusCode: 200,
body: JSON.stringify({message: 'Success'})
}
@约翰罗滕斯坦,请你联系文档团队,看看他们能否更新文档?我曾经联系过@SebastienStomarq,他说他已经和docs团队谈过了,但到目前为止还没有更新文档。现在,我们要回答的大多数问题都是关于
async/await
与context
和callback
调用结合使用,造成了绝对的混乱。如果文档未修复,这些问题将不断出现。@ThalesMinussi您可以单击文档页面上的“反馈”按钮,该按钮将发送给文档团队。但是,如果您想写一个更详细的解释,请随时发电子邮件给我,我会向文档团队提出。(我不是节点人,所以最好让熟悉大多数问题的人为他们记录问题。)@JohnRotenstein Perfect。当我有时间写详细的解释时,我会这样做。谢谢你抽出时间给我回电话。也许开源文档会是一个好主意…@ThalesMinussi AWS文档可以在github上获得,因此您可以提交请求(但我不确定所有手册都在那里)。@JohnRotenstein我已经着手创建了PR。让我们看看你们AWS和社区的反应。谢谢你们的回复。这很有道理,我已经相应地重构了lambda函数,但是问题仍然存在。既然我正在等待sendMessages承诺,那么我是否应该对响应执行任何操作以终止/退出lambda处理程序中的函数?非常欢迎。不是真的…那个返回{message:'Success}
块应该能够处理它。除非这是来自API网关的调用。是这样吗?如果是这样,您需要添加状态码并将主体字符串化。我会更新我的答案。