Python 使用Flask和eventlet响应并发请求
我尝试设置一个最小的Flask应用程序,它使用即时响应并发请求,而不是一个接一个地阻塞和响应请求(就像标准的Flask调试Web服务器那样) 先决条件:Python 使用Flask和eventlet响应并发请求,python,flask,eventlet,flask-socketio,Python,Flask,Eventlet,Flask Socketio,我尝试设置一个最小的Flask应用程序,它使用即时响应并发请求,而不是一个接一个地阻塞和响应请求(就像标准的Flask调试Web服务器那样) 先决条件: pip install Flask pip install eventlet 根据我目前在互联网上的发现,它应该是这样工作的: # activate eventlet import eventlet eventlet.monkey_patch() from flask import Flask import datetime from t
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秒后第一个选项卡完成后返回
这里怎么了?
顺便问一下,鉴于预期的并发用户很少(最多5个),这是否就是Flask通常所说的“生产就绪Web服务器”
顺便说一句,当我运行Web服务器时,根据文档,如果安装了eventlet,它会自动选择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)
不会神奇地将您的代码变成一个可以异步处理请求的多线程野兽(它仍然非常神奇和可怕)
如中所示,您需要使用启动wsgi
服务器
如果您想要一个标准的解决方案,可以看看如何使用nginx和uwsgi来启动flask应用程序。您可能还对利用创建完整多线程wsgi处理程序的痛苦的项目感兴趣。当您运行app.run(debug=True)
时,您明确地告诉Flask在基于Werkzeug的开发web服务器上运行您的应用程序。您是否已加载eventlet并不重要
如果要在eventlet web服务器上运行应用程序,必须启动eventlet web服务器,该服务器根据启动方式如下:
wsgi.server(eventlet.listen(('', 8000)), your_app)
这或多或少是
socketio.run()
在我的Flask socketio扩展中所做的事情,有选择地处理SSL稍微复杂一些。执行此操作的代码行为:。如果您环顾这些行,您将看到有三个不同的启动代码块,一个用于werkzeug,一个用于eventlet,另一个用于gevent。它们都不一样。好吧,我明白了,切换到野兽模式并不是那么容易。然而,flask socketio
如何处理这个问题呢?至少,在“Deployment/Embedded server”(部署/嵌入式服务器)下会显示,请注意,在安装eventlet或gevent时,socketio.run(应用程序)会运行一个生产就绪的服务器。
,无需进一步详细说明。既然使用uWsgi/NGINX,那么像上面那样使用flask socketio
有什么缺点吗?太好了!从eventlet文档中的示例中,我不清楚必须将Flask app对象传递给wsgi.server命令,因此这个基于Flask的示例非常有用。
wsgi.server(eventlet.listen(('', 8000)), your_app)