通过 node.js 将大文件上传到 S3 存储桶 [关闭]

问题描述 投票:0回答:0

我的 Web 应用程序 (react-node.js) 的用户应该能够将大型 zip 文件 (~20gb) 上传到 S3 存储桶。但在将文件上传到 S3 之前,我需要验证压缩文件并从 zip 中获取一些信息以将它们保存在数据库中。我使用

multer
busboy
进行上传,但我看到当用户上传文件时服务器内存迅速减少。对于像 50-400mb 这样的小文件,它可以工作。但是在上传完成之前,每次请求都会中断重文件。在浏览器的网络面板上,我看到 ERR:CONNECTION_RESET 错误。 在这种情况下上传大文件的正确方法是什么?

尝试使用 multer 和 busboy 包,但它们都使用服务器内存并导致问题。

Busboy 配置:

public busboyInterceptor(req: Request): Promise<IFileMetadata> {
    return new Promise((resolve, reject) => {
      let metadata = {
        fieldname: '',
        encoding: '',
        mimetype: '',
        originalname: '',
        path: '',
        destination: '',
        filename: '',
        size: 0,
      };

      const busboy = Busboy({ headers: req.headers });

      busboy.on('file', (name, file, info) => {
        const destFolder = path.join(
          global.__basedir,
          this.configService.get<string>('FILE_UPLOAD_FOLDER'),
        );
        const fileName = `${uuid()}.zip`;
        const filePath = `${destFolder}/${fileName}`;

        metadata.fieldname = name;
        metadata.encoding = info.encoding;
        metadata.mimetype = info.mimeType;
        metadata.originalname = info.filename;
        metadata.destination = destFolder;
        metadata.path = filePath;
        metadata.filename = fileName;

        if (!ArchiveMimetypes.includes(info.mimeType)) {
          throw new BadRequestException('Accepted mime type is zip ');
        }

        file.on('data', (data) => {
          metadata.size += data.length;
        });

        file
          .pipe(fs.createWriteStream(filePath, { flags: 'a' }))
          .on('error', (e) => {
            console.error('Failed write file', e);
            throw new HttpException(
              'Internal server error',
              HttpStatus.INTERNAL_SERVER_ERROR,
            );
          });
      });

      busboy.on('error', (e) => {
        console.error('Failed upload file', e);
        throw new HttpException(
          'Internal server error',
          HttpStatus.INTERNAL_SERVER_ERROR,
        );
      });

      busboy.on('finish', () => {
        console.log(metadata);

        console.log('File uploaded');
        resolve(metadata);
      });

      req.pipe(busboy);
    });

多重配置:

    createMulterOptions(): MulterModuleOptions {
    const destinationPath = path.join(
      global.__basedir,
      this.configService.get<string>('FILE_UPLOAD_FOLDER'),
    );

    return {
      fileFilter(req, file, callback) {
        if (ArchiveMimetypes.includes(file.mimetype)) {
          callback(null, true);
        } else {
          callback(
            new BadRequestException('Accepted mime type is zip '),
            false,
          );
        }
      },
      storage: diskStorage({
        destination: destinationPath,
        filename: function (req, file, callback) {
          const uniqueSuffix = uuid();
          callback(null, uniqueSuffix + `.zip`);
        },
      }),
      limits: {
        fileSize: FileSizes.GB,
      },
    };
   }
node.js reactjs amazon-s3 multer busboy
© www.soinside.com 2019 - 2024. All rights reserved.