我知道我可以将Flask与Apache或其他web服务器连接起来。但是,我正在考虑将Flask作为一个独立的服务器,同时为多个客户端提供服务。
这可能吗?我是否必须处理生成多个线程并管理它们?
在Flask中使用简单的app.run()在一个线程上创建一个同步服务器,一次只能服务一个客户端。正是出于这个原因,它适用于低需求的受控环境(即开发、调试)。
app.run()
生成线程并自己管理它们可能也不会让你走得太远,因为Python GIL。
也就是说,你仍然有一些不错的选择。Gunicorn是一个可靠的,易于使用的WSGI服务器,它可以让你生成多个worker(独立的进程,所以没有GIL担忧),甚至附带异步的工人,它将加快你的应用程序(并使它更安全),而你几乎不需要做任何工作(特别是使用Flask)。
不过,即使是Gunicorn也不应该直接公开曝光。在生产中,它应该用于更健壮的HTTP服务器后面;nginx倾向于适合Gunicorn和Flask。
flask.Flask.run接受额外的关键字参数(**options),它将这些参数转发给werkzeug.serving.run_simple——其中两个参数是threaded(一个布尔值)和processes(你可以将其设置为一个大于1的数字,以便让werkzeug生成多个进程来处理请求)。
flask.Flask.run
**options
werkzeug.serving.run_simple
threaded
processes
从Flask 1.0开始,threaded默认为True,因此对于Flask的最新版本,默认的开发服务器将能够默认地同时为多个客户端服务。对于较旧版本的Flask,你可以显式地传递threaded=True来启用此行为。
True
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的参考实现,而不是一个生产就绪的web服务器。如果你打算在生产中使用Flask(假设"production"不是一个低流量的内部应用程序,并发用户不超过10个),确保它站在一个真正的web服务器后面(参见Flask的文档中题为部署选项的部分,以获得一些建议的方法)。
serving.run_simple
wsgiref
2020年的小贴士:
从Flask 1.0开始,它默认启用多线程(源),你不需要做任何事情,只需要升级它:
$ pip install -U flask
如果你正在使用flask run而不是旧版本的app.run(),你可以使用命令选项(--with-threads/--without-threads)控制线程行为:
flask run
--with-threads/--without-threads
$ flask run --with-threads
它与app.run(threaded=True)相同
app.run(threaded=True)