【发布时间】:2013-01-26 16:13:53
【问题描述】:
我知道我可以将 Flask 与 Apache 或其他 Web 服务器链接起来。但是,我正在考虑将 Flask 作为同时为多个客户端提供服务的独立服务器运行。
这可能吗?我必须处理生成多个线程并管理它们吗?
【问题讨论】:
我知道我可以将 Flask 与 Apache 或其他 Web 服务器链接起来。但是,我正在考虑将 Flask 作为同时为多个客户端提供服务的独立服务器运行。
这可能吗?我必须处理生成多个线程并管理它们吗?
【问题讨论】:
flask.Flask.run 接受额外的关键字参数 (**options),并将其转发到 werkzeug.serving.run_simple - 其中两个参数是 threaded(布尔值)和 processes(您可以将其设置为大于一的数字让 werkzeug 产生多个进程来处理请求)。
threaded 在 Flask 1.0 中默认为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 的参考实现,而不是生产就绪的 Web 服务器。如果你打算在生产环境中使用 Flask(假设“生产环境”不是一个不超过 10 个并发用户的低流量内部应用程序),请确保将它放在一个真正的 Web 服务器后面(参见 Flask 文档中标题为Deployment Options 一些建议的方法)。
【讨论】:
processes=100 并对此感到满意吗?就我而言,我只需要静态文件,不需要 HTTP Post 方法。我的要求是,我想将所有 Flask 线程作为我父应用程序的一部分运行,以便它们都可以共享变量。
在 Flask 中使用简单的app.run() 在单个线程上创建一个同步服务器,一次只能为一个客户端提供服务。正是出于这个原因,它旨在用于需求较低的受控环境(即开发、调试)。
由于the Python GIL,生成线程并自行管理它们可能也不会让您走得太远。
也就是说,您仍然有一些不错的选择。 Gunicorn 是一个可靠的、易于使用的 WSGI 服务器,它可以让你生成多个 worker(独立的进程,所以不用担心 GIL),甚至还附带了 asynchronous workers,它可以加快你的应用程序(并使其更安全) ) 几乎没有工作(尤其是使用 Flask)。
不过,即使是 Gunicorn 也不应该直接公开曝光。在生产中,应该在更健壮的 HTTP 服务器后面使用它; nginx 往往与 Gunicorn 和 Flask 配合得很好。
【讨论】:
gunicorn app:app 127.0.0.1:8080 而不是python app.py 运行你的应用程序。 Nginx 将充当公共服务,公开您的私有 Gunicorn 运行应用程序(a reverse-proxy),隐藏各种较低级别的 HTTP 实现细节,可能直接提供静态文件等。
2020 年的提示:
从 Flask 1.0 开始,它默认启用多线程 (source),你不需要做任何事情,只需升级它:
$ pip install -U flask
如果您在旧版本中使用 flask run 而不是 app.run(),则可以使用命令选项 (--with-threads/--without-threads) 控制线程行为:
$ flask run --with-threads
和app.run(threaded=True)一样
【讨论】: