我可以仅用Flask app.run()独立服务多个客户端吗?
我知道我可以把Flask和Apache或者其他网络服务器连接起来。但是,我在想能不能让Flask自己单独运行,给多个用户同时提供服务。
这样做可以吗?我需要自己处理多个线程的创建和管理吗?
3 个回答
2020年的小贴士:
从Flask 1.0开始,它默认支持多线程,也就是说你不需要做任何额外的设置,只要把它升级到新版本就可以了,升级的方法是:
$ pip install -U flask
如果你用的是 flask run
而不是 app.run()
,并且版本比较旧,你可以通过命令选项来控制是否使用多线程,选项是 --with-threads
或 --without-threads
:
$ flask run --with-threads
这和 app.run(threaded=True)
是一样的效果。
在Flask中使用简单的 app.run()
方法,会创建一个单线程的同步服务器,这样的服务器一次只能服务一个客户。这种方式适合在需求不高的环境中使用,比如开发和调试。
自己创建和管理线程可能也不会有太大帮助,因为有一个叫做 Python GIL 的限制。
不过,你还是有一些不错的选择。 Gunicorn 是一个简单易用的WSGI服务器,可以让你启动多个工作进程(这些是独立的进程,所以不受GIL的影响),而且它还提供了 异步工作进程,可以让你的应用运行得更快(而且更安全),而你几乎不需要做额外的工作(特别是在使用Flask时)。
不过,即使是Gunicorn,也不应该直接暴露在公共网络上。在生产环境中,它应该放在一个更强大的HTTP服务器后面; nginx 通常和Gunicorn以及Flask搭配得很好。
flask.Flask.run
这个方法可以接受一些额外的参数(**options
),这些参数会传递给werkzeug.serving.run_simple
。其中有两个参数是 threaded
(一个布尔值)和 processes
(你可以设置为大于1的数字,这样werkzeug就会启动多个进程来处理请求)。
从Flask 1.0开始,threaded
的默认值是 True
,所以在最新版本的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(假设“生产环境”不是一个低流量的内部应用,且同时用户不超过10个),一定要把它放在一个真正的网络服务器后面(可以查看Flask文档中关于部署选项的部分,了解一些建议的方法)。