单个Flask进程接收多少个并发请求?

Car*_*son 113 python wsgi flask gunicorn

我正在使用Flask构建一个应用程序,但我不太了解WSGI,它是HTTP基础,Werkzeug.当我开始使用gunicorn和4个工作进程为Flask应用程序提供服务时,这是否意味着我可以处理4个并发请求?

我的意思是并发请求,而不是每秒或其他任何请求.

谢谢!

Rya*_*ona 154

当您运行开发服务器时app.run(),您将获得一个同步过程,这意味着一次最多处理1个请求.

通过在其默认配置中坚持使用Gunicorn并简单地增加其数量--workers,您获得的实质上是许多进程(由Gunicorn管理),每个进程都像app.run()开发服务器一样.4名工人== 4个并发请求.这是因为Gunicorn sync默认使用其包含的工作类型.

需要注意的是Gunicorn还包括异步工人,即它是重要的eventletgevent(也tornado,但是这最好与龙卷风框架中使用,它似乎).通过使用该--worker-class标志指定其中一个异步工作程序,您获得的是Gunicorn管理许多异步进程,每个异步进程管理自己的并发.这些进程不使用线程,而是使用协同程序.基本上,在每个进程中,一次只能发生一件事(1个线程),但是当对象等待外部进程完成时(想想数据库查询或等待网络I/O),对象可以被"暂停".

这意味着,如果您使用的是Gunicorn的异步工作者之一,那么每个工作人员一次只能处理多个请求.最好的工人数量取决于应用程序的性质,环境,运行的硬件等.更多细节可以在Gunicorn的设计页面上找到,并说明gevent如何在其介绍页面上工作.

  • Flask 开发服务器从 v1.0 开始默认使用线程(https://github.com/pallets/flask/pull/2529) (4认同)
  • Gunicorn现在支持自19版以来的"真正"线程.参见[this](http://docs.gunicorn.org/en/stable/design.html#how-many-threads)和[this](http:// docs .gunicorn.org/EN /稳定/ settings.html#线). (3认同)
  • 如何跟踪哪些资源共享(以及如何共享)以及线程/进程之间完全分开的资源?例如,当我要在由Gunicorn处理并在Flask处理程序中使用的多个进程之间共享巨大的数据结构时,我将如何处理? (2认同)

jd.*_*jd. 29

Flask将同时处理每个线程的一个请求.如果你有2个进程,每个进程有4个线程,那就是8个并发请求.

Flask不会产生或管理线程或进程.这是WSGI网关(例如gunicorn)的责任.


Dar*_*nus 24

目前,有一个比已经提供的解决方案简单得多的解决方案.运行应用程序时,您只需将threaded=True参数传递给app.run()调用,例如:

app.run(host="your.host", port=4321, threaded=True)
Run Code Online (Sandbox Code Playgroud)

根据我们在werkzeug文档中可以看到的另一个选项是使用processes参数,该参数接收数字> 1,表示要处理的最大并发进程数:

  • threads - 进程是否应该在单独的线程中处理每个请求?
  • 进程 - 如果大于1,则在新进程中处理每个请求,直到达到此最大并发进程数.

就像是:

app.run(host="your.host", port=4321, processes=3) #up to 3 processes
Run Code Online (Sandbox Code Playgroud)

关于更多信息run()方法在这里,和博客文章,导致我找到解决方案和API引用.

  • 谢谢(你的)信息。值得注意的是,运行文档指出它不应该在生产环境中使用,因为它不符合安全或性能要求。 (6认同)

use*_*786 9

不 - 你绝对可以处理更多.

重要的是要记住,在内心深处,假设您正在运行单个核心机器,CPU实际上一次只运行一条指令*.

也就是说,CPU只能执行一组非常有限的指令,并且每个时钟周期不能执行多条指令(许多指令甚至需要多于1个滴答).

因此,我们在计算机科学中谈论的大多数并发性是软件并发性.换句话说,有一些软件实现层可以从我们这里抽象出底层CPU,并让我们认为我们正在同时运行代码.

这些"事物"可以是进程,它们是并发运行的代码单元,因为每个进程都认为它在自己的世界中运行,拥有自己的非共享内存.

另一个例子是线程,它是进程内部允许并发的代码单元.

您的4个工作进程能够处理4个以上请求的原因是它们将触发线程来处理越来越多的请求.

实际的请求限制取决于所选的HTTP服务器,I/O,OS,硬件,网络连接等.

祝好运!

*指令是CPU可以运行的基本命令.示例 - 添加两个数字,从一条指令跳转到另一条指令

  • _“在深处,假设您运行的是单核机器,CPU 实际上一次只运行一条指令*”_ 这在现代机器上是不正确的。大多数现代 CPU 都是[流水线](https://en.wikipedia.org/wiki/Instruction_pipelined) 和[超标量](https://en.wikipedia.org/wiki/Superscalar_processor),其中即使单个核心也有多个执行单元和指令解码器,将从软件方面看到的“机器代码”转换为分派到各个执行单元的实际硬件微操作。 (6认同)
  • 澄清一下,早在那时,CPU 实际上就直接执行可执行文件(机器代码)中的数字指令。每个 CPU 参考都有一个指令时序图,显示每个指令占用了多少个时钟周期,包括任何内存参考。因此,您只需将时间相加即可知道任何代码段需要多长时间。现代CPU 根本不是这样的。一个有趣的例外是 [BeagleBone](https://beagleboard.org/black),它具有一个现代超标量 ARM 处理器和两个具有固定指令时序的老式“PRU”处理器。 (2认同)
  • 为了澄清这一点,当我说“现代”时,我将其用作 ARM/Intel/AMD 芯片等处理器的宽松速记 - 流水线、超标量等。当然,也有一些现代处理器以固定时序以旧方式工作每条指令,就像我提到的 BeagleBone PRU 和各种新的微控制器。(现在回到 Gunicorn!) (2认同)