用Flask甚至

2024-03-29 01:42:12 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图建立一个最小的Flask应用程序,它使用eventlet立即响应并发请求,而不是阻塞和响应一个接一个的请求(就像标准的Flask调试web服务器那样)。

先决条件:

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)

当运行此文件,然后在webbrowser选项卡中打开http://localhost:5000/longTask时,当它仍在处理使用http://localhost:5000/shortTask打开另一个选项卡时,我希望第二个选项卡在第一个选项卡仍在加载时立即返回。然而,与在标准的Werkzeug服务器上运行此项类似,第二个选项卡仅在第一个选项卡在30秒后完成后返回

这里怎么了? 顺便问一下,这是否是Flask通常所说的“生产就绪Web服务器”,因为只有很少的并发用户(最多5个)?

顺便说一下,当我使用the Flask-socketio library运行web服务器时,根据文档,该服务器会自动选择eventlet(如果已安装),然后它会按预期工作。

带烧瓶的完整示例:

# 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)

Tags: fromimport服务器appflasktaskdatetimesleep
2条回答

当您运行app.run(debug=True)时,您明确地告诉Flask在基于Werkzeug的开发web服务器上运行您的应用程序。加载eventlet并不重要。

如果要在eventlet web服务器上运行应用程序,则必须启动eventlet web服务器,根据the documentation,该服务器按如下方式启动:

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

这或多或少是socketio.run()在我的Flask SocketIO扩展中所做的,对于可选地处理SSL来说要复杂一些。执行此操作的代码行是:https://github.com/miguelgrinberg/Flask-SocketIO/blob/539cd158f49ce085151911cb63edbacd0fa37173/flask_socketio/init.py#L391-L408。如果您查看这些行,您将看到有三个不同的启动代码块,一个用于werkzeug,一个用于eventlet,一个用于gevent。他们都不一样。

import eventlet
eventlet.monkey_patch()

不会神奇地把你的代码变成一个可以异步处理请求的多线程野兽(它仍然非常神奇和可怕)。

this example中可以看到,您需要使用eventlet wsgi's implementation启动wsgi服务器。

如果你想要一个标准的解决方案,看看如何使用nginx和uwsgi来启动flask应用程序。您还可能对项目Spawning感兴趣,该项目利用了创建一个完整的多线程wsgi处理程序的痛苦。

相关问题 更多 >