Как мое веб-приложение Heroku Flask может поддерживать N пользователей, одновременно загружающих файл изображения? - PullRequest
0 голосов
/ 10 июля 2020

Я работаю над веб-приложением Flask, используя Heroku. В рамках приложения пользователи могут запросить загрузку изображения с сервера. Это вызывает функцию, которая затем должна получить несколько изображений из моего облачного хранилища (всего около 500 КБ), применить некоторое форматирование и вернуть одно изображение (около 60 КБ). Это выглядит примерно так:

@app.route('/download_image', methods=['POST'])
def download_image():
    # Retrieve about 500 KB of images from cloud storage
    base_images = retrieve_base_images(request.form)
    
    # Apply image formatting into a single image
    formatted_image = format_images(base_images)

    # Return image of about 60 KB for download
    formatted_image_file = io.BytesIO()
    formatted_image.save(formatted_image_file, format='JPEG')
    formatted_image_data = formatted_image_file.getvalue()
    return Response(formatted_image_data,
                    mimetype='image/jpeg',
                    headers={'Content-Disposition': 'attachment;filename=download.jpg'})

Мой файл Procfile -

web: gunicorn my_app:app

Как я могу спроектировать / настроить его для поддержки N одновременных пользователей? Скажем, например, я хочу убедиться, что мое приложение может поддерживать 100 разных пользователей, которые все запрашивают загрузку изображения одновременно. С несколькими движущимися частями я не уверен, как сделать это go.

Кроме того, если кто-то запрашивает загрузку, но затем теряет соединение rnet до завершения загрузки, это может вызвать какую-то блокировки, которая может бесконечно останавливаться, или этот поток / процесс автоматически истечет по таймауту после короткого периода и, следовательно, будет обрабатываться без проблем? При необходимости я готов добавить дополнительные динамометрические установки.

1 Ответ

1 голос
/ 10 июля 2020

Запуск нескольких рабочих процессов Gunicorn :

Gunicorn разделяет несколько системных процессов в каждом динамометрическом стенде, чтобы приложение Python могло поддерживать несколько одновременных запросов, не требуя, чтобы они были потоками. сейф. В терминологии Gunicorn они называются рабочими процессами (не путать с рабочими процессами Heroku, которые работают в своих собственных динамометрах).

Мы рекомендуем установить для этого переменную конфигурации настройка. Gunicorn автоматически учитывает переменную среды WEB_CONCURRENCY, если она установлена.

heroku config:set WEB_CONCURRENCY=3

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

Однако вы не сможете приблизиться к 100 на бесплатном стенде. Этот раздел находится между двумя предыдущими в документации:

Каждый разветвленный системный процесс потребляет дополнительную память. Это ограничивает количество процессов, которые вы можете запустить на одном динамометрическом стенде. При типичном объеме памяти приложения Django вы можете рассчитывать на запуск 2–4 рабочих процессов Gunicorn на free, hobby или standard-1x dyno. Ваше приложение может допускать изменение этого, в зависимости от конкретных c требований к памяти вашего приложения.

Даже если ваше приложение очень легкое, вы, вероятно, не сможете до go более 6 рабочих на одном небольшом стенде. Потребуется добавление дополнительных дино и / или увеличение количества запускаемых вами дино.

Вам действительно нужно поддерживать 100 одновременных запросов? Если у вас работает четыре рабочих, запросы четырех пользователей могут обрабатываться одновременно. Если пятый сделает запрос, на этот запрос просто не ответят, пока один из рабочих не освободится. Обычно это разумно.

Если для выполнения вашего запроса требуется неоправданно много времени, у вас есть несколько вариантов помимо добавления дополнительных рабочих:

  • Можете ли вы кэшировать сгенерированные изображения?
  • Можете ли вы немедленно вернуть ответ, создать изображения в фоновом задании, а затем уведомить пользователя, что изображения готовы? При некоторой модной интерфейсной работе это может быть довольно прозрачно для конечного пользователя.

Правильное решение будет зависеть от вашего конкретного c варианта использования. Удачи!

...