当前位置: 首页 > 知识库问答 >
问题:

自调用lambda调用超时

危晨
2023-03-14

我们正在尝试开发一个自调用的lambda来成批处理S3文件。lambda角色具有附加调用所需的策略。

以下是自调用lambda的代码:


export const processFileHandler: Handler = async (
  event: S3CreateEvent,
  context: Context,
  callback: Callback,
) => {
  let bucket = loGet(event, 'Records[0].s3.bucket.name');
  let key = loGet(event, 'Records[0].s3.object.key');
  let totalFileSize = loGet(event, 'Records[0].s3.object.size');
  const lastPosition = loGet(event, 'position', 0);
  const nextRange = getNextSizeRange(lastPosition, totalFileSize);

  context.callbackWaitsForEmptyEventLoop = false;

  let data = await loadDataFromS3ByRange(bucket, key, nextRange);


  await database.connect();

  log.debug(`Successfully connected to the database`);

  const docs = await getParsedDocs(data, lastPosition);
  log.debug(`upserting ${docs.length} records to database`);
  if (docs.length) {
    try {
         // upserting logic
      log.debug(`total documents added: ${await docs.length}`);
    } catch (err) {
      await recurse(nextRange.end, event, context);
      log.debug(`error inserting docs: ${JSON.stringify(err)}`);
    }
  }

  if (nextRange.end < totalFileSize) {
    log.debug(`Last ${context.getRemainingTimeInMillis()} milliseconds left`);
    if (context.getRemainingTimeInMillis() < 10 * 10 * 10 * 6) {
      log.debug(`Less than 6000 milliseconds left`);
      log.debug(`Invoking next iteration`);
      await recurse(nextRange.end, event, context);
      callback(null, {
        message: `Lambda timed out processing file, please continue from LAST_POSITION: ${nextRange.start}`,
      });
    }

  } else {
    callback(null, { message: `Successfully completed the chunk processing task` });
  }
};

其中递归是对同一个lambda的调用调用。其余的事情都按预期工作,只要调用堆栈出现在这个调用请求上,它就会超时:

const recurse = async (position: number, event: S3CreateEvent, context: Context) => {
  let newEvent = Object.assign(event, { position });

  let request = {
    FunctionName: context.invokedFunctionArn,
    InvocationType: 'Event',
    Payload: JSON.stringify(newEvent),
  };

  let resp = await lambda.invoke(request).promise();
  console.log('Invocation complete', resp);

  return resp;
};

这是记录到CloudWatch的堆栈跟踪:

{
    "errorMessage": "connect ETIMEDOUT 63.32.72.196:443",
    "errorType": "NetworkingError",
    "stackTrace": [
        "Object._errnoException (util.js:1022:11)",
        "_exceptionWithHostPort (util.js:1044:20)",
        "TCPConnectWrap.afterConnect [as oncomplete] (net.js:1198:14)"
    ]
}

共有1个答案

李锦
2023-03-14

创建自调用lambda函数不是一个好主意。如果出现错误(也可能是AWS端的错误处理程序调用),lambda函数可能会重新运行几次。很难监控和调试。

我建议使用步骤函数。我相信本教程可以帮助使用Lambda迭代循环

如果您不想处理Step函数,那么可以为SQS队列创建一个Lambda触发器。如果希望下次运行lambda函数,则向队列传递一条消息

 类似资料:
  • 我正在使用WebSocket ApiGateway和AWS Lambda集成。当我尝试使用方法向客户机发送数据时,Lambda函数总是超时而不会出现任何错误消息。只有超时消息才会登录到CloudWatch中: 我做错了什么?

  • 我有一个由S3推送事件触发的AWS Lambda。lambda将调用一个API,这将触发一个长时间运行的进程。我认识到我可以配置S3异步调用lambda函数,因此S3不会等待响应,但我很想知道我是否可以配置lambda异步调用我的API。我不希望lambda在过程完成时等待几分钟。有人能给我指出一些概述这个过程的留档吗?提前谢谢。

  • 我创建了一个节点lambda函数,它对Aurora数据库进行简单调用。当我在控制台中测试该函数时,查询返回,我可以在日志中看到结果,但回调似乎永远不会被调用,所以我的lambda函数超时了。我无法找出问题所在。希望这里有人能指出我的问题。 生成的Cloudwatch日志如下所示。。。

  • 好了,我说完了。请有人帮帮我:( 我不知道js和lambda是怎么工作的 null 最令人困惑的是!这个b给我这个测试结果: 运行1: DynamoDb是空的,这里我们看不到DynamoDb.BatchWriteItem结果的日志。

  • 问题内容: 我正在Python中调用一个函数,该函数可能会停滞并迫使我重新启动脚本。 如何调用该函数或将其包装在其中,以便如果花费的时间超过5秒,脚本将取消该函数并执行其他操作? 问题答案: 如果在上运行,则可以使用信号包: 调用后10秒钟,将调用处理程序。这引发了一个异常,你可以从常规Python代码中拦截该异常。 该模块不能很好地与线程配合使用(但是,谁可以呢?) 请注意,由于发生超时时会引发

  • 我想在另一个类中通过它的子类调用一个超级类的方法。 例如:类a及其子类CA,CA重写a的方法f() 类B中的CA实例: .... 感谢任何帮助:)