Nodejs 上传文件到 S3 内存管理
Nodejs 上传文件到 S3 内存管理
目前结构是前端把文件上传至 node 后端,然后后端上传到 S3. 目前前端后端都做了 validation. 但是如果直接通过 api endpoint 上传,后端会把所有东西先 load 到内存后才能做 validation,通过验证之后上传 S3. 现在有两个问题
1. 如果用户使用 api endpoint 上传,跳过前端验证,后端无法在上传完毕之前知道文件大小。如何在刚开始上传的时候就检测文件大小并且阻止用户上传大文件?
2. 目前如果用户上传文件失败或者文件比较大,占用内存过多,服务器容易直接爆炸…
*不能直接从前端直接上传,前端只能消化内部 APIs,不能直接连 S3.
求解决方法。
按固定字节分割文件,按照分割后的子文件做 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-sdk
和fs
模块实现文件上传的示例,同时注重内存管理:
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
语法使得代码更加简洁易读。