我正在用 Flask 构建一个应用程序,但是我对 WSGI 知之甚少,它是 HTTP 基础,Werkzeug。当我开始使用 gunicorn 和4个 worker 进程服务 Flask 应用程序时,这是否意味着我可以处理4个并发请求?
我的意思是并发请求,而不是每秒的请求或其他任何东西。
不,你绝对可以处理更多。
重要的是要记住,在内心深处,假设您运行的是单个核心机器,那么 CPU 实际上一次只运行一条指令 * 。
也就是说,CPU 只能执行非常有限的一组指令,而且每个时钟滴答不能执行多于一条指令(许多指令甚至需要多于一个时钟滴答)。
因此,我们在计算机科学中讨论的最多的并发是软件并发。 换句话说,有一些软件实现层从我们这里抽象出底层的 CPU,使我们认为我们正在并发地运行代码。
这些“东西”可以是进程,它们是并发运行的代码单元,每个进程都认为自己在自己的世界中运行,拥有自己的非共享内存。
另一个例子是线程,它是进程中允许并发的代码单元。
您的4个辅助进程之所以能够处理4个以上的请求,是因为它们将启动线程来处理越来越多的请求。
实际的请求限制取决于 HTTP 服务器的选择、 I/O、操作系统、硬件、网络连接等。
祝你好运!
* 指令是 CPU 可以运行的非常基本的命令。例子-添加两个数字,从一个指令跳转到另一个
Flask 将同时处理每个线程的一个请求。如果有两个进程,每个进程有4个线程,那么就是8个并发请求。
Flask 不会产生或管理线程或进程,这是 WSGI 网关(如 gunicorn)的责任。
当运行开发服务器时——这是通过运行 app.run()得到的,您将获得一个同步进程,这意味着一次最多处理1个请求。
app.run()
通过将 Gunicorn 放在它的默认配置前面,并简单地增加 --workers的数量,您实际上得到的是许多进程(由 Gunicorn 管理) ,每个进程的行为都像 app.run()开发服务器。4 worker = = 4个并发请求。这是因为 Gunicorn 默认使用其包含的 ABc2 worker 类型。
--workers
需要注意的是,Gunicorn 还包括异步工作者,即 eventlet和 gevent(以及 tornado,但似乎最适合用于龙卷风框架)。通过使用 --worker-class标志指定其中一个异步工作者,您可以得到 Gunicorn 管理许多异步进程,每一个管理自己的并发。这些进程不使用线程,而是使用协程。基本上,在每个进程中,一次仍然只能发生一件事(1个线程) ,但是当对象等待外部进程完成时(想想数据库查询或等待网络 I/O) ,它们可以被“暂停”。
eventlet
gevent
tornado
--worker-class
这意味着,如果您使用的是 Gunicorn 的异步工作者之一,那么每个工作者一次可以处理多个请求。究竟有多少工作人员是最好的,这取决于你的应用程序的性质、它的环境、它所运行的硬件等等。更多的细节可以在 独角兽的设计页面和 关于 Gevent 如何工作的笔记的介绍页面上找到。
目前有一个 简单多了解决方案比已经提供的解决方案。运行应用程序时,只需将 threaded=True参数传递给 app.run()调用,如:
threaded=True
app.run(host="your.host", port=4321, threaded=True)
根据我们在 Werkzeug 医生中看到的内容,另一个选项是使用 processes参数,它接收到一个大于1的数字,表示需要处理的并发进程的最大数量:
processes
线程-进程是否应该在单独的线程中处理每个请求? 进程-如果大于1,则处理新进程中的每个请求,直到并发进程的最大数目为止。
比如:
app.run(host="your.host", port=4321, processes=3) #up to 3 processes
关于 run()方法 给你的更多信息,以及引导我找到解决方案和 api 参考的 博客文章。
run()
注意: 在 Flask 文档的 run()方法中,它指出在生产环境中使用它是不被鼓励的,因为(引用) : < em > “虽然 Flask 的内置服务器轻量级且易于使用,但它不适合生产,因为它不能很好地扩展规模。”
但是,他们确实指向他们的 部署方案页面,以便在进入生产环境时获得推荐的方法。