Узел JS – данные Stream от Busboy до AWS S3

Я пытаюсь загрузить файл на s3 через ec2. Мой первый подход: полностью загрузить файл в ec2, а затем загрузить этот файл в s3. Этот подход не является хорошим, потому что время передачи от ec2 до s3 является пустой тратой времени.

В настоящее время я пытаюсь использовать stream загрузки bbboy в stream загрузки s3, чтобы загрузка в ec2, а затем ec2 в s3 выполнялась одновременно как stream поддержки метода s3 «upload», как upload Body.

Вот мой код –

router.post('/s3StreamUpload', function(req, res, next) { var busboy = new Busboy({headers: req.headers}); busboy.on('file', function (fieldname, file, filename, encoding, mimetype) { console.log('Before Upload: ' + new Date()); console.log('File [' + fieldname + ']: filename: ' + filename + ', encoding: ' + encoding + ', mimetype: ' + mimetype); var s3 = new AWS.S3({ params: {Bucket: 'sswa', Key: filename, Body: file}, options: {partSize: 5 * 1024 * 1024, queueSize: 10} // 5 MB }); s3.upload().on('httpUploadProgress', function (evt) { console.log(evt); }).send(function (err, data) { console.log('After Upload: ' + new Date()); console.log(err, data); }); }); busboy.on('field', function(fieldname, val, fieldnameTruncated, valTruncated, encoding, mimetype) { console.log('Field [' + fieldname + ']: value: ' + inspect(val)); }); busboy.on('finish', function() { console.log('Done parsing form!'); res.writeHead(303, { Connection: 'close', Location: '/' }); res.end(); }); req.pipe(busboy); }); 

У меня есть сомнения, действительно ли это загрузка на s3 одновременно как stream? Есть ли недостатки такого подхода?

    Чтобы проверить, работает ли многопользовательская streamовая загрузка на S3 или нет, я взял журнал времени в трех точках исполнения –

    1. Перед началом загрузки с клиента ( uploadStartTime )
    2. После загрузки в EC2 ( busboyFinishTime )
    3. После переноса на S3 ( s3UploadFinishTime )

    Затем я бегу от EC2. После загрузки различной длины видеофайлов (36,1 МБ, 33,3 МБ, 52,5 МБ) я заметил, что части передаются на S3 сразу для каждого 5 МБ (как я определил), загруженного в EC2. При загрузке деталей на S3 вы увидите журнал следующей строки. Он покажет прогресс загрузки части файла с номером детали.

     console.log(evt); 

    Для всех трех загрузок busboyFinishTime и s3UploadFinishTime одинаковы или вряд ли разница в 1 секунду.

    Пример: при загрузке 52,5 МБ

     { "uploadStartTime": "2016-04-28T14:19:51.365Z", "busboyFinishTime": "2016-04-28T14:22:26.292Z", "s3UploadFinishTime": "2016-04-28T14:22:26.558Z" } 

    Полный код:

     router.post('/s3StreamUpload', function(req, res, next) { var busboy = new Busboy({headers: req.headers}); var uploadStartTime = new Date(), busboyFinishTime = null, s3UploadFinishTime = null; busboy.on('file', function (fieldname, file, filename, encoding, mimetype) { console.log('File [' + fieldname + ']: filename: ' + filename + ', encoding: ' + encoding + ', mimetype: ' + mimetype); var s3 = new AWS.S3({ params: {Bucket: 'sswa', Key: filename, Body: file}, options: {partSize: 5 * 1024 * 1024, queueSize: 10} // 5 MB }); s3.upload().on('httpUploadProgress', function (evt) { console.log(evt); }).send(function (err, data) { s3UploadFinishTime = new Date(); if(busboyFinishTime && s3UploadFinishTime) { res.json({ uploadStartTime: uploadStartTime, busboyFinishTime: busboyFinishTime, s3UploadFinishTime: s3UploadFinishTime }); } console.log(err, data); }); }); busboy.on('field', function(fieldname, val, fieldnameTruncated, valTruncated, encoding, mimetype) { console.log('Field [' + fieldname + ']: value: ' + inspect(val)); }); busboy.on('finish', function() { console.log('Done parsing form!'); busboyFinishTime = new Date(); if(busboyFinishTime && s3UploadFinishTime) { res.json({ uploadStartTime: uploadStartTime, busboyFinishTime: busboyFinishTime, s3UploadFinishTime: s3UploadFinishTime }); } }); req.pipe(busboy); }); 

    По моим наблюдениям, я уверен, что это одно из лучших решений для загрузки файла на S3 через EC2 с использованием REST API, развернутого на EC2.

    Вы пытаетесь загрузить на S3 прямо из браузера? Если это так, вы можете использовать presigned-put для прямого браузера для загрузки S3.

    Вот как вы создаете назначенный URL-адрес PUT, используя minio-js

     s3Client.presignedPutObject('my-bucketname', 'my-objectname', 1000, function(e, presignedUrl) { if (e) return console.log(e) console.log(presignedUrl) }) 

    Теперь вы передаете этот назначенный URL-адрес клиенту браузера, который может использовать XMLHttpRequest, чтобы напрямую передать файл S3.