Могу ли я обслуживать несколько клиентов, используя только Flask app.run () в качестве автономного?

202

Я знаю, что могу связать Flask с Apache или другими веб-серверами. Но я думал о запуске Flask в качестве отдельного сервера, обслуживающего несколько клиентов одновременно.

Это возможно? Нужно ли обрабатывать несколько потоков и управлять ими?

ATOzTOA
источник

Ответы:

295

flask.Flask.runпринимает дополнительные ключевые аргументы ( **options), которые он передаетwerkzeug.serving.run_simple - два из этих аргументов threaded(логические) и processes(для которых можно установить число больше единицы, чтобы werkzeug порождал более одного процесса для обработки запросов).

threaded по умолчанию True используется Flask 1.0, поэтому для последних версий Flask сервер разработки по умолчанию сможет одновременно обслуживать несколько клиентов. Для более старых версий Flask вы можете явно передать, threaded=Trueчтобы включить это поведение.

Например, вы можете сделать

if __name__ == '__main__':
    app.run(threaded=True)

обрабатывать несколько клиентов, используя потоки способом, совместимым со старыми версиями Flask, или

if __name__ == '__main__':
    app.run(threaded=False, processes=3)

сказать Werkzeug создать три процесса для обработки входящих запросов, или просто

if __name__ == '__main__':
    app.run()

обрабатывать несколько клиентов, используя потоки, если вы знаете, что будете использовать Flask 1.0 или более позднюю версию.

При этом Werkzeug упаковывает пакет serving.run_simpleстандартной библиотеки wsgiref- и этот пакет содержит эталонную реализацию WSGI, а не готовый к работе веб-сервер. Если вы собираетесь использовать Flask в работе (при условии, что «production» не является внутренним приложением с низким трафиком и имеет не более 10 одновременно работающих пользователей), убедитесь, что оно установлено на реальном веб-сервере (см. Раздел документации Flask, озаглавленный Варианты развертывания для некоторых предлагаемых методов).

Шон Виейра
источник
2
Что делать, если я смотрю максимум 100 пользователей? Могу ли я просто назначить processes=100и быть счастливым с этим? В моем случае мне нужны только статические файлы, а не методы HTTP Post. Мое требование - я хочу запустить все потоки Flask как часть моего родительского приложения, чтобы они могли совместно использовать переменные.
ATOzTOA
4
Chuckles - @ATOzTOA - нет, что, вероятно , будет весьма непродуктивным (процессы являются относительно дорогими, и если вы не делаете много работы в каждом запросе нет никаких причин , почему 4 или 8 процессы не должны быть достаточно). Тем не менее, если вы отображаете только статический контент, вам лучше использовать сервер, оптимизированный для этого (Apache, ngnix, IIS).
Шон Виейра
2
Кроме того, вам обычно не нужно обмениваться переменными между запросами - если вы это сделаете, вам нужно либо ограничить себя одним процессом, либо использовать какое-либо внешнее взаимодействие (Redis, база данных, файловая система и т. Д.), Поэтому что каждый из ваших процессов остается синхронизированным.
Шон Виейра
3
@ATOzTOA - если вы не можете раскрутить лучший сервер, тогда я просто поверну его и посмотрю, что произойдет. Если он работает плохо под нагрузкой, вы можете развернуть его на другом веб-сервере.
Шон Виейра
2
@ATOzTOA, относительно вашего вопроса о том, почему вы не можете одновременно указывать «потоки» и «процессы», см. Код здесь: werkzeug.readthedocs.org/en/latest/_modules/werkzeug/serving
pyrho
62

Использование простого app.run()изнутри Flask создает один синхронный сервер в одном потоке, способный одновременно обслуживать только одного клиента. Именно по этой причине он предназначен для использования в контролируемых средах с низким спросом (т.е. разработка, отладка).

Появление потоков и управление ими самостоятельно, вероятно, не слишком далеко продвинет вас из-за Python GIL .

Тем не менее, у вас все еще есть несколько хороших вариантов. Gunicorn - это надежный и простой в использовании сервер WSGI, который позволит вам порождать несколько рабочих (отдельные процессы, поэтому GIL не беспокоится) и даже поставляется с асинхронными рабочими , которые ускорят ваше приложение (и сделают его более безопасным) с минимальными затратами. не работать с вашей стороны (особенно с Flask).

Тем не менее, даже Gunicorn, вероятно, не должен быть публично разоблачен. В производстве его следует использовать за более надежным HTTP-сервером; nginx хорошо сочетается с Gunicorn и Flask.

Райан Артекона
источник
17
не совсем. Gunicorn - это питон, а nginx - нет. это не то, как вы бы их использовали. Gunicorn позволит вам запустить ваше приложение как gunicorn app:app 127.0.0.1:8080вместо python app.py. Nginx будет выступать в качестве общедоступной службы, предоставляющей доступ к вашему частному приложению, запускаемому Gunicorn (обратный прокси-сервер) , скрывая всевозможные подробности реализации HTTP более низкого уровня, возможно, напрямую обслуживая статические файлы и т. Д.
Ryan Artecona
Flask с app.run (threadaded = True) отлично работает на Apache2, используя mod_wsgi flask.palletsprojects.com/en/1.1.x/deploying/mod_wsgi
MortenB