Nodejs 上传文件到 S3 内存管理

Nodejs 上传文件到 S3 内存管理
目前结构是前端把文件上传至 node 后端,然后后端上传到 S3. 目前前端后端都做了 validation. 但是如果直接通过 api endpoint 上传,后端会把所有东西先 load 到内存后才能做 validation,通过验证之后上传 S3. 现在有两个问题

1. 如果用户使用 api endpoint 上传,跳过前端验证,后端无法在上传完毕之前知道文件大小。如何在刚开始上传的时候就检测文件大小并且阻止用户上传大文件?
2. 目前如果用户上传文件失败或者文件比较大,占用内存过多,服务器容易直接爆炸…

*不能直接从前端直接上传,前端只能消化内部 APIs,不能直接连 S3.

求解决方法。


8 回复

按固定字节分割文件,按照分割后的子文件做 validation。validation(f1, f2, f3, …) = validation(f)


看你的 validation 情况了,我们每天有很多 10G-50G 的文件也要上传到 s3,但是我们都是一行行验证 使用 stream 读入输入数据 接了一个 zlib.createGunzip() 接一个 readlinestream 然后在 readline 的 line 事件验证 最后 stream 到 s3
楼主可以参考下

文件大小限制可以通过 content-length 解决, 浏览器会带有这个 header 的。超限直接抛错就行

至于 validation , 是什么目的的 validation? signature ?

一直很纳闷为什么只有 nodejs 的节点有这种主题色

在前端就分隔好?

后端分割,有一张数据库表记录分割前文件名和分割后子文件名,以及分割后所有子文件的 validation 信息,以及分割后子文件在 s3 的地址。这样无论是存/取/ validation,都可以用这张表

在Node.js中将文件上传到Amazon S3时,内存管理是一个重要的考虑因素。为了避免内存泄漏和高效处理大文件,可以使用流(Streams)来逐步读取和上传文件。以下是一个使用aws-sdkfs模块实现文件上传的示例,同时注重内存管理:

const AWS = require('aws-sdk');
const fs = require('fs');
const path = require('path');

// 配置S3客户端
const s3 = new AWS.S3({
  accessKeyId: 'YOUR_ACCESS_KEY',
  secretAccessKey: 'YOUR_SECRET_KEY',
  region: 'YOUR_REGION'
});

// 上传文件函数
async function uploadFile(filePath, bucket, key) {
  const fileStream = fs.createReadStream(filePath);

  const params = {
    Bucket: bucket,
    Key: key,
    Body: fileStream,
    ContentType: 'application/octet-stream' // 根据需要设置
  };

  try {
    await s3.upload(params).promise();
    console.log('File uploaded successfully');
  } catch (err) {
    console.error('Error uploading file:', err);
  }
}

// 使用示例
const filePath = path.join(__dirname, 'example.txt');
uploadFile(filePath, 'your-bucket-name', 'example.txt').catch(console.error);

在这个示例中,我们使用fs.createReadStream来创建一个读取流,这样文件内容会逐步从磁盘读取并上传到S3,而不是一次性加载到内存中。这种方式在处理大文件时特别有效,可以避免内存占用过高的问题。同时,使用async/await语法使得代码更加简洁易读。

回到顶部