Загрузка больших файлов из веб-браузера и передача в Amazon S3

В настоящее время у нас есть небольшое веб-приложение, частью которого является загрузка файлов. В настоящее время мы используем Plupload на клиенте с включенным чанкингом для загрузки больших файлов. Файлы сохраняются на сервере приложений, и фрагменты добавляются по мере их появления.

Теперь мы переходим на Amazon S3 для хранения файлов с возможностью использования нескольких серверов приложений. Мне трудно, как обращаться с этими кусками. Я пытался последовать их примеру, но у меня проблемы. Мясо того, что я пробую, выглядит так:

UploadPartRequest uploadRequest = new UploadPartRequest()
    .withBucketName(bucket).withKey(key)
    .withUploadId(uploadId).withPartNumber(partNumber)
    .withPartSize(bytes.length)
    .withInputStream(new ByteArrayInputStream(bytes));

s3Client.uploadPart(uploadRequest);

У меня проблема в том, что мне нужно каким-то образом знать идентификатор загрузки чанка. У меня есть, когда я получаю InitiateMultipartUploadResult от инициализации загрузки, но как связать это с более поздними фрагментами, которые появляются? Я подумал, что мог бы отправить его с первым ответом, а затем отправить его обратно с каждым запросом куска. Это не казалось слишком далеко.

Затем я обнаружил, что для завершения загрузки мне нужно List<PartETag> с PartETag возвращается с каждой загрузки на Amazon S3. Итак, мой следующий вопрос был, как мне сохранить все эти PartETag В то время как куски загружаются из браузера? Моей первой мыслью было, что я могу отправить PartETag каждого куска в ответе, а затем сохранить эти стороны клиента. Я не уверен, есть ли способ узнать, когда загружается последний кусок, чтобы я мог отправить все эти PartETag s. Если это не так, я просто должен отправить все те, которые у меня есть каждый раз, и тогда только последний запрос будет использовать их. Все это кажется немного хакерским для меня.

Итак, я думаю, что кто-то должен был иметь дело с этим раньше. Есть ли хороший, стандартный способ сделать это?

Я думал о создании файла на сервере приложений, а затем об отправке его на S3, но с несколькими серверами приложений не гарантируется, что фрагменты окажутся в одном месте.

Еще одна мысль, которая у меня возникла, - это сохранить всю эту информацию в базе данных во время загрузки, но я не был уверен, что мне нужно идти в базу данных при каждом запросе куска. Есть ли другие варианты, кроме этого?

Я ценю любую помощь, которую может оказать каждый.

2 ответа

Попробуйте наше решение IaaS:

https://uploadcare.com/

Он поддерживает размер файла до 5 ГБ. Вот статья об успешном варианте использования для загрузки больших файлов с помощью нашей системы:

https://community.skuidify.com/skuid/topics/how_to_upload_large_files_using_uploadcare_com

Поправьте меня, если я ошибаюсь, но, как я понимаю ваш вопрос, ваши веб-серверы действуют как прокси между браузером и клиентом.

У меня проблема в том, что мне нужно каким-то образом знать идентификатор загрузки чанка. У меня есть это, когда я получаю InitiateMultipartUploadResult от инициализации загрузки, но как мне связать это с более поздними порциями, которые появляются?

На BeforeUpload Вы можете добавить uploadId как параметр строки запроса, как в этом ответе

Моей первой мыслью было, что я могу отправить PartETag каждого чанка в ответе, а затем сохранить их на стороне клиента.

Это кажется хорошей идеей, затем изменить строку запроса, как указано выше, в 'ChunkUploaded', чтобы добавить только что полученный PartETag, таким образом переводя все ранее полученные PartETag с каждым запросом. Не уверен, что возможно изменить строку запроса между порциями, или если вы можете синхронно выполнить некоторую обработку до начала загрузки следующей порции, но я бы сказал, что стоит попробовать.

Я не уверен, есть ли способ узнать, когда загружается последний кусок, чтобы я мог отправить все эти PartETag.

Это можно найти в примерах php в загрузке plupload: два параметра POST отправляются plupload на сервер

  • chunks: общее количество фрагментов загрузки (0, если загрузка не фрагментирована)
  • chunk: индекс текущей загружаемой части

Последний кусок это когда chunks==0 || chunk==chunks-1

Другие вопросы по тегам