Ответ на параллельные запросы с помощью Flask и eventlet

Я пытаюсь настроить минимальное приложение колбы, которое использует eventlet мгновенно реагировать на параллельные запросы, а не блокировать и отвечать на один запрос за другим (как это делает стандартный веб-сервер отладки колбы).

требования:

pip install Flask
pip install eventlet

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

# activate eventlet
import eventlet
eventlet.monkey_patch()

from flask import Flask

import datetime
from time import sleep

# create a new Flask application
app = Flask(__name__)

# a short running task that returns immediately
@app.route('/shortTask')
def short_running_task():
  start = datetime.datetime.now()
  return 'Started at {0}, returned at {1}'.format(start, datetime.datetime.now())

# a long running tasks that returns after 30s
@app.route('/longTask')
def long_running_task():
  start = datetime.datetime.now()
  sleep(30)
  return 'Started at {0}, returned at {1}'.format(start, datetime.datetime.now())

# run the webserver
if __name__ == '__main__':
    app.run(debug=True)

при запуске этого файла, то открывающий тег http://localhost:5000/longTask на вкладке webbrowser и пока он все еще обрабатывает открытие другой вкладки с http://localhost:5000/shortTask, Я ожидал бы, что вторая вкладка вернется немедленно, пока первая вкладка все еще загружается. Однако, как и при запуске этого на стандартном сервере Werkzeug, вторая вкладка возвращается только после того, как первая завершена после 30-х годов.

что здесь не так? Кстати, будет ли это то, что обычно называют "готовым к производству веб-сервером" для Flask, учитывая, что есть только несколько одновременных пользователей ожидается (5 максимум)?

кстати, когда я использую колбу-socketio библиотека для запуска веб-сервера, который, согласно документации, автоматически выбирает eventlet, если он установлен, то он работает так, как ожидалось.

полный пример с колбой-socketio:

# activate eventlet
import eventlet
eventlet.monkey_patch()

from flask import Flask
from flask_socketio import SocketIO

import datetime
from time import sleep

# create a new Flask application
app = Flask(__name__)

# activate Flask-socketio
socketio = SocketIO(app)

# a short running task that returns immediately
@app.route('/shortTask')
def short_running_task():
  start = datetime.datetime.now()
  return 'Started at {0}, returned at {1}'.format(start, datetime.datetime.now())

# a long running tasks that returns after 30s
@app.route('/longTask')
def long_running_task():
  start = datetime.datetime.now()
  sleep(30)
  return 'Started at {0}, returned at {1}'.format(start, datetime.datetime.now())

# run the webserver with socketio
if __name__ == '__main__':
    socketio.run(app, debug=True)

2 ответов


при выполнении app.run(debug=True) вы явно говорите Flask запустить приложение на веб-сервере разработки, который основан на Werkzeug. Не имеет значения, что вы загрузили eventlet.

Если вы хотите запустить приложение на веб-сервере eventlet, вы должны запустить веб-сервер eventlet, который в соответствии с документация запускается следующим образом:

wsgi.server(eventlet.listen(('', 8000)), your_app)

Это более или менее то, что socketio.run() делает в моей колбе-расширение SocketIO, с немного большей сложностью дополнительно обрабатывать SSL. Строк кода, которые делают это, являются: https://github.com/miguelgrinberg/Flask-SocketIO/blob/539cd158f49ce085151911cb63edbacd0fa37173/flask_socketio/init.py#L391-L408. Если вы посмотрите вокруг этих линий, вы увидите, что есть три разных запуске куски кода, один для сверла, для eventlet и gevent для. Они все разные.


import eventlet
eventlet.monkey_patch()

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

Как вы можете видеть в , вам нужно запустить wsgi сервер с помощью реализация eventlet wsgi.

Если вы хотите стандартное решение, посмотрите, как использовать nginx и uwsgi для запуска приложения flask. Вы также можете быть заинтересованы в проекте нерестовые это усиливает боль создания полного многопоточного обработчика wsgi.