首页 > 解决方案 > 建议处理多个 lambda 调用的方法

问题描述

主要问题: 外部 API 调用成功后 Lambda 函数未退出,随后触发多个外部 API 调用。

我有一个 lambda 函数,它在事件发生时侦听松弛事件,调用 lambda 函数。我使用一些条件检查过滤这些事件,当目标事件发生时,我进行外部 API 调用。

以上所有方法都有效,但是,每个事件都会触发外部 API 调用多次(如果成功,则应该为 1 时触发约 4 次)。

幂等 性 - 人们通常将此问题与幂等性联系起来,但是,鉴于它在条件块内的外部 API 调用被触发了额外的时间,我不认为这是一个问题。

寻找一些建议的方法

我在下面附加了 lambda 函数:

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);
    }
};

预期行为

标签: aws-lambdaslack

解决方案


问题(您不是第一个也不会是最后一个提出此类问题的人,AWS 需要尽快修复文档)是因为您正在async/await与电话混淆。context.donecallback()

如果你的函数已经是async,那么一直坚持下去await,忘记contextcallback对象。

看到那sendMessagesasync,因此它返回一个 Promise,但你不对该 Promise 做任何事情。你应该await在上面。我已经相应地更改了您的代码并删除了contextcallback对象,您不需要它们。

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 Gateway 调用,则您需要返回带有字符串化主体的 2xx 状态代码(或 4xx 和 5xx,以防出现错误),以便它可以正确终止,如下所示:

return {
        statusCode: 200,
        body: JSON.stringify({message: 'Success'})
      }

推荐阅读