Ограничение размера при загрузке из облачного хранилища с помощью App Engine - PullRequest
0 голосов
/ 19 декабря 2018

tldr: существует ли ограничение на размер файла для отправки файла из облачного хранилища в веб-браузер моего пользователя для загрузки?Я неправильно использую API-интерфейс Storage Python или мне нужно увеличить ресурсы, установленные моим файлом YAML App Engine?

Это просто проблема с загрузками.Загрузка отлично работает до любого размера файла, используя чанкинг.


Симптомы

Я создал приложение для передачи файлов в App Engine Python 3.7 Standard.Пользователи могут загружать файлы любого размера, и это работает хорошо.Но пользователи сталкиваются с тем, что при загрузке полученного файла из облачного хранилища возникает ограничение по размеру.

Самый большой файл, который я успешно отправил и получил за весь процесс загрузки / выгрузки, составил 29 мегабайт.Затем я отправил себе файл размером 55 мегабайт, но когда я попытался получить его в качестве загрузки, Flask выдает мне эту ошибку:

Error: Server Error The server encountered an error and could not complete your request. Please try again in 30 seconds.


Структура приложения

Чтобы создать приложение для передачи файлов, я использовал Flask для настройки двух сервисов internal и external, каждый со своим собственным файлом маршрутизации Flask, собственной веб-страницей / доменом и собственными YAML-файлами.

Чтобы протестировать приложение, я посещаю созданную мной веб-страницу internal.Я использую его для загрузки файла в виде фрагментов в мое приложение, которое успешно создает фрагменты в облачном хранилище.Затем я захожу в консоль Google Cloud Platform от имени администратора, и когда я смотрю на Cloud Storage, он показывает 55-мегабайтный файл, который я загрузил.Это позволит мне загрузить его напрямую через консоль облачной платформы, и файл хорош.

(До этого момента этот процесс работал даже для файла объемом 1,5 гигабайта.)

Затем я захожу на мою external веб-страницу как пользователь без прав администратора.Я использую форму, чтобы попытаться получить тот же файл для загрузки.Я получаю вышеуказанную ошибку.Однако весь этот процесс не содержит ошибок для моего тестового файла размером 29 мегабайт или меньше.

Журналы отладчика Stacktrace для этой службы показывают:

logMessage: "The process handling this request unexpectedly died. This is likely to cause a new process to be used for the next request to your application. (Error code 203)"


Возможные решения

Я добавил следующие строки в свой файл external YAML службы:

resources: memory_gb: 100 disk_size_gb: 100

Ошибка осталась прежней.Видимо, это не предел системных ресурсов?

Возможно, я неправильно использую Python API для облачного хранилища.Я импортирую storage из google.cloud.Вот где мое приложение отвечает на запрос пользователя POST, отправив пользователю запрошенный файл:

@app.route('/download', methods=['POST'])
def provide_file():
    return external_download()

Эта часть находится в external_download:

    storage_client = storage.Client()
    bucket = storage_client.get_bucket(current_app.cloud_storage_bucket)
    bucket_filename = request.form['filename']
    blob = bucket.blob(bucket_filename)

    return send_file(io.BytesIO(blob.download_as_string()),
                     mimetype="application/octet-stream",
                     as_attachment=True,
                     attachment_filename=filename)

Нужно ли мнереализовать чанкинг для загрузки, а не только для загрузки?

1 Ответ

0 голосов
/ 21 декабря 2018

Я бы не рекомендовал использовать метод Flask send_file() для управления передачей больших файлов. Методы обработки файлов Flask были предназначены для использования разработчиками или API для обмена системными сообщениями в основном, такими как журналы, файлы cookieи другие легкие объекты.

Кроме того, метод download_as_string() действительно может скрывать ограничение буфера, я воспроизвел ваш сценарий и получил такое же сообщение об ошибке с файлами размером более 30 МБ, однако я не смог найти большеинформация о таком ограничении.Это может быть преднамеренным, вызванным целью метода (загрузка контента в виде строки, не приспособленной для больших объектов).

Проверенные способы эффективной обработки передачи файлов с помощью Cloud Storage и Python:

  • Используйте методы API Cloud Storage напрямую, до загрузка и загрузка объектов без использования Flask.Как упоминалось в @FridayPush, оно разгрузит ваше приложение, и вы сможете контролировать доступ с помощью Подписанных URL .

  • Используйте API Blobstore ,простое, легкое и простое решение для передачи файлов, полностью интегрированное с корзинами GCS и предназначенное для такого типа ситуаций.

  • Используйте встроенный модуль Python Requests , требует создания собственных обработчиков для связи с GCS.

...