我可以单独使用Flask app.run()服务多个客户端吗?

问题:我可以单独使用Flask app.run()服务多个客户端吗?

我知道我可以将Flask与Apache或其他Web服务器链接。但是,我当时正在考虑将Flask作为独立的服务器运行,同时为多个客户端提供服务。

这可能吗?我是否需要处理产生多个线程并进行管理?

I know I can link Flask with Apache or other web servers. But, I was thinking of running Flask as a standalone server serving multiple clients simultaneously.

Is this possible? Do I have to handle spawning multiple threads and managing them?


回答 0

flask.Flask.run接受**options转发给它的其他关键字参数()werkzeug.serving.run_simple-其中两个参数是threaded(布尔值)和processes(您可以将其设置为大于1的数字以使werkzeug产生多个进程来处理请求)。

threaded默认True版本自Flask 1.0起,因此对于最新版本的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文档标题为“ 一些建议方法的部署选项)。

flask.Flask.run accepts additional keyword arguments (**options) that it forwards to werkzeug.serving.run_simple – two of those arguments are threaded (a boolean) and processes (which you can set to a number greater than one to have werkzeug spawn more than one process to handle requests).

threaded defaults to True as of Flask 1.0, so for the latest versions of Flask, the default development server will be able to serve multiple clients simultaneously by default. For older versions of Flask, you can explicitly pass threaded=True to enable this behaviour.

For example, you can do

if __name__ == '__main__':
    app.run(threaded=True)

to handle multiple clients using threads in a way compatible with old Flask versions, or

if __name__ == '__main__':
    app.run(threaded=False, processes=3)

to tell Werkzeug to spawn three processes to handle incoming requests, or just

if __name__ == '__main__':
    app.run()

to handle multiple clients using threads if you know that you will be using Flask 1.0 or later.

That being said, Werkzeug’s serving.run_simple wraps the standard library’s wsgiref package – and that package contains a reference implementation of WSGI, not a production-ready web server. If you are going to use Flask in production (assuming that “production” is not a low-traffic internal application with no more than 10 concurrent users) make sure to stand it up behind a real web server (see the section of Flask’s docs entitled Deployment Options for some suggested methods).


回答 1

app.run()在Flask中使用simple from在单个线程上创建单个同步服务器,该服务器一次只能服务一个客户端。正是出于这个原因,它旨在用于需求较低的受控环境(即开发,调试)中。

由于Python GIL,因此自行生成线程并自行管理它们也不会使您走得太远。

也就是说,您仍然有一些不错的选择。Gunicorn是一个坚固且易于使用的WSGI服务器,它使您可以产生多个工作程序(独立的进程,因此无需担心GIL),甚至还带有异步工作程序,这些工作程序可以在不增加成本的情况下加快您的应用程序(并使其更安全)。无需您做任何事情(尤其是使用Flask)。

不过,即使Gunicorn也可能不应该直接公开曝光。在生产中,应在功能更强大的HTTP服务器之后使用它。Nginx倾向于与Gunicorn和Flask搭配使用。

Using the simple app.run() from within Flask creates a single synchronous server on a single thread capable of serving only one client at a time. It is intended for use in controlled environments with low demand (i.e. development, debugging) for exactly this reason.

Spawning threads and managing them yourself is probably not going to get you very far either, because of the Python GIL.

That said, you do still have some good options. Gunicorn is a solid, easy-to-use WSGI server that will let you spawn multiple workers (separate processes, so no GIL worries), and even comes with asynchronous workers that will speed up your app (and make it more secure) with little to no work on your part (especially with Flask).

Still, even Gunicorn should probably not be directly publicly exposed. In production, it should be used behind a more robust HTTP server; nginx tends to go well with Gunicorn and Flask.