Загрузка больших файлов из веб-браузера и передача в 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:
Он поддерживает размер файла до 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