【问题标题】:Lambda function is not triggered for all the s3 image upload所有 s3 图片上传都不会触发 Lambda 函数
【发布时间】:2021-08-24 03:17:16
【问题描述】:

我有如下的 s3 存储桶,

我的桶

  • 一个/
  • b/
  • c/

其中 myBucket 是一个 s3 存储桶,a、b、c 是该存储桶内的关键文件夹。 我会将图片上传到a/。 s3 事件通知将触发 SQS,然后触发 lambda 函数,该函数执行删除图像背景并上传到 b/ 文件夹的过程。

这里的问题是,例如,如果我将一个包含大约 26 张图像的文件夹上传到 s3 中,则只有 23 或 22 张图像被 lambda 触发,并且只有那些图像被处理。

由于某种原因,s3 没有触发所有图像,或者我应该在我的 lambda 函数中配置什么?

这是我的功能代码

exports.handler = async(event, context, callback) => {
  try {
    console.log(event.Records[0]);
    var json = JSON.parse(event.Records[0]['body']);
    console.log('json: '+json);
    json = JSON.parse(json['Message']);
    json = json['Records'][0]['s3'];
    console.log(json);

    var srcBucket = json['bucket']['name'];
    console.log('srcBucket: ' + srcBucket);
    var srcKey = decodeURIComponent(json['object']['key'].replace(/\+/g, ' '));
    console.log('srcKey: ' + srcKey);
    var str = (srcKey.split('/').pop()).split('.')[0];
    console.log('str: ' + str);

    if (str != '') {
      var folderPath = srcKey.substr(srcKey.indexOf('/') + 1).split('.')[0];
      folderPath = folderPath.substring(0, folderPath.lastIndexOf('/'));
      console.log('folderPath: ' + folderPath);

      const params1 = { Bucket: srcBucket, Key: srcKey };
      var origimage = await s3.getObject(params1).promise();
      var destObject = await origimage.Body;
      var destKey = 'removebg/' + folderPath + '/' + str + '.jpg';

      var options = {
        'method': 'POST',
        'url': 'https://api.remove.bg/v1.0/removebg',
        'headers': {
          'X-Api-Key': 'xxxxxxxxxxx'
        },
        formData: {
          'image_file': destObject,
          'size': 'auto'
        },
        encoding: null
      };

      request(options, function(error, response, body) {

        if (error) {
          console.log(error);
          sendmessage(error, 'Error removing image background', arn, srcBucket + '/' + srcKey, destBucket + destKey);
        }

        var params = { Bucket: destBucket, Key: destKey, Body: body };

        s3.upload(params, function(err, data) {
          if (err) {
            console.log('Error uploading data: ', err);
            sendmessage(err, 'Error uploading transparent image to s3', arn, srcBucket + '/' + srcKey, destBucket + destKey);

          }
          else { console.log('Successfully uploaded data to ' + destBucket); }
        });
      });
    }
  }
  catch (e) {
    console.log(e);
  }
  callback(null, 'All done!');
};

请告诉我。提前致谢。

【问题讨论】:

  • 你检查过 Lambda 函数的 cloudwatch 日志吗?它可能会说明一些事情。我猜这个函数超时了。
  • 存储桶是否有版本?
  • 请编辑您的问题并向我们展示您的 AWS Lambda 函数代码。具体来说,您是否遍历了event 中提供的所有Records
  • @shimo 是的,我确实检查了日志功能。我想这不是超时问题
  • @Marcin 我还没有完成存储桶版本控制。有必要吗?

标签: amazon-web-services amazon-s3 aws-lambda


【解决方案1】:

我认为您的问题在于以下几点:

    console.log(event.Records[0]);
    var json = JSON.parse(event.Records[0]['body']);
    console.log('json: '+json);
    json = JSON.parse(json['Message']);
    json = json['Records'][0]['s3'];

您的函数只查看提供给该函数的 first 记录。可以为 Lambda 函数提供多个事件,因此您的函数应遍历 Records 条目并处理所有提供的事件。

它应该做这样的事情:

  for record in event.Records:
    console.log(record);
    var json = JSON.parse(record['body']);
    console.log('json: '+json);
    json = JSON.parse(json['Message']);
    json = record['s3'];

【讨论】:

  • 很抱歉最近遇到这个问题。你能告诉我如何循环吗?因为我使用的是 SNS 通知,当图像上传到 s3 文件夹时会收到通知,这又会触发 SQS。此 SQS 将触发 lambda。所以我相信 SQS 会一次有一个记录。不是吗?
  • 我添加了一个代码示例。试试看它是否有效!或者,至少,开始记录len(event.Records) 以验证是否通过了多条记录。
  • 非常感谢@John。有效。或者,我们也可以将 SQS 批量大小设为 1,默认为 10。
猜你喜欢
  • 2020-05-16
  • 2021-08-27
  • 2021-06-24
  • 2016-03-26
  • 2021-10-10
  • 2020-02-09
  • 2019-08-03
  • 2017-03-16
相关资源
最近更新 更多