簡體   English   中英

結果不一致,導致從AWS Lambda調用API

[英]Inconsistent results making API call from AWS Lambda

讓我為這個糟糕的代碼提前表示歉意。 我幾乎有零節點經驗,並且在后端使用React應用程序和Elixir編寫了所有JS。 我正在努力在NodeJS中編寫正確的Lambda函數,並且基本上已經將Googling / SO / trial和error等中的內容拼湊在一起。

我在做什么如下:

  • 用戶想要上傳文件,以便將一些信息發送到后端。
  • 后端生成一個預簽名密鑰。
  • 前端將文件發送到S3。
  • S3觸發事件並執行Lambda
  • Lambda現在檢查是否有mimetype,如果它是錯誤的文件,則將從S3存儲桶中刪除該文件,並向我的后端進行DELETE API調用,以告訴它刪除照片上傳所屬的行。

當我在s3.deleteObject調用中對后端進行API調用時,我遇到的困難是,我得到的結果異常不一致。 很多時候,它會在同一Lambda執行中連續發送兩個刪除請求。 有時候,就像它甚至從未調用過后端,只是運行並顯示完整而沒有真正將任何內容記錄到Cloudwatch。

我的代碼如下:

    const aws = require('aws-sdk');

    const s3 = new aws.S3({apiVersion: '2006-03-01'});

    const fileType = require('file-type');

    const imageTypes = ['image/gif', 'image/jpeg', 'image/png'];

    const request = require('request-promise');

    exports.handler = async (event, context) => {
      // Get the object from the event and show its content type
      const bucket = event.Records[0].s3.bucket.name;
      const key = decodeURIComponent(
        event.Records[0].s3.object.key.replace(/\+/g, ' ')
      );

      const params = {
        Bucket: bucket,
        Key: key,
      };

      try {
        const {Body} = await s3.getObject(params).promise();

        const fileBuffer = new Buffer(Body, 'base64');
        const fileTypeInfo = fileType(fileBuffer);

        if (
          typeof fileTypeInfo !== 'undefined' &&
          fileTypeInfo &&
          imageTypes.includes(fileTypeInfo.mime)
        ) {
          console.log('FILE IS OKAY.');
        } else {
          await s3
            .deleteObject(params, function(err, data) {
              console.log('FILE IS NOT AN IMAGE.');
              if (err) {
                console.log('FAILED TO DELETE.');
              } else {
                console.log('DELETED ON S3.  ATTEMPTING TO DELETE ON SERVER.');

                const url =
                  `http://MYSERVERHERE:4000/api/event/${params.Key.split('.')[0]}`;

                const options = {
                  method: 'DELETE',
                  uri: url,
                };

                request(options)
                  .then(function(response) {
                    console.log('RESPONSE: ', response);
                  })
                  .catch(function(err) {
                    console.log('ERROR: ', err);
                  });
              }
            })
            .promise();
        }
        return Body;
      } catch (err) {
        const message = `Error getting object ${key} from bucket ${bucket}. Make sure they exist and your bucket is in the same region as this function.`;
        console.log(message);
        throw new Error(message);
      }
    };

這讓我發瘋了好幾天了。 感謝您提供任何幫助來解釋為什么我會從這樣的Lambda函數獲得意想不到的結果。

請檢查后更新適當的await使用其他部分

請嘗試以下代碼。

exports.handler = async (event, context) => {
  // Get the object from the event and show its content type
  const bucket = event.Records[0].s3.bucket.name;
  const key = decodeURIComponent(
    event.Records[0].s3.object.key.replace(/\+/g, ' ')
  );

  const params = {
    Bucket: bucket,
    Key: key,
  };

  try {
    const {Body} = await s3.getObject(params).promise();

    const fileBuffer = new Buffer(Body, 'base64');
    const fileTypeInfo = fileType(fileBuffer);

    if (
      typeof fileTypeInfo !== 'undefined' &&
      fileTypeInfo &&
      imageTypes.includes(fileTypeInfo.mime)
    ) {
      console.log('FILE IS OKAY.');
    } else {
      await s3.deleteObject(params).promise(); //fail then catch block execute
        console.log('DELETED ON S3.  ATTEMPTING TO DELETE ON SERVER.');

        const url =
          `http://MYSERVERHERE:4000/api/event/${params.Key.split('.')[0]}`;

        const options = {
          method: 'DELETE',
          uri: url,
        };

        let response = await request(options); ////fail then catch block execute
        console.log(response);
      }
    return Body;
  } catch (err) {
    console.log(err);
    const message = `Error getting object ${key} from bucket ${bucket}. Make sure they exist and your bucket is in the same region as this function.`;
    console.log(message);
    throw new Error(message);
  }
};

最終,S3刪除操作在所有區域都是一致的。

因此,作為標准AWS(獲取的相關信息),

  • 進程將刪除現有對象並立即嘗試讀取它。 在完全傳播刪除之前,Amazon S3可能會返回刪除的數據。
  • 進程刪除現有對象並立即在其存儲桶中列出鍵。 在完全傳播刪除之前,Amazon S3可能會列出刪除的對象。

參考: https : //docs.aws.amazon.com/AmazonS3/latest/dev/Introduction.html#ConsistencyModel

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM