关于并发:如何在PHP中处理并发请求(使用 – 线程,线程池或子进程)

how are concurrent requests handled in PHP (using - threads, thread pool or child processes)

我了解PHP支持处理多个并发连接,根据服务器的不同,可以按照此答案中所述进行配置。

服务器如何管理多个连接?是为每个请求分叉子进程,还是使用线程处理,还是使用线程池处理?

链接的答案说进程是分叉的,然后注释中的作者说线程或进程,如果使用子进程、线程或线程池来处理请求,这会让人困惑。


正如我所知,每个Web服务器都有自己的处理多文件同时请求的类型。通常,Apache2会为每个新请求分叉一个子进程。但是您可以按照链接的stackoverflow答案中所述的方式配置这种行为。

例如,nginx在一个线程中获取每个请求(像node.js那样异步处理新连接),或者有时使用缓存(如配置的那样;nginx也可以用作负载平衡器或HTTP代理)。为应用程序选择正确的Web服务器是一回事。

Apache2可能是一个非常好的Web服务器,但是当您想要在生产中使用它时,需要更多的负载平衡。但是,当有多个持续时间短的连接或者甚至是根本不改变的文档(或者使用缓存)时,它也有很好的功能。

nginx是非常好的,如果你期望许多持久的连接,以某种方式长的处理时间。你不需要那么多的负载平衡。

我希望,我能帮你解决这个问题;)

资料来源:

https://httpd.apache.org/docs/2.4/mod/worker.html网站

https://anturis.com/blog/nginx-vs-apache/

我建议您也看看:PHP中什么是线程安全的或非线程安全的?


在做了一些研究之后,我得出了以下结论。

重要的是要考虑如何将PHP服务器设置为能够深入了解它。要自行设置服务器和PHP,可能有三种可能性:

1)使用php作为模块(对于许多服务器,php具有直接模块接口(也称为sapi))。

2)CGI

3)FASCGI

考虑到case 1php作为模块,在这种情况下,该模块与Web服务器本身集成,现在它把球完全放在Web服务器上,它如何处理分叉过程、使用线程、线程池等方面的请求。

对于模块,Apache mod_php似乎非常常用,而Apache本身使用流程和线程在两个模型中处理请求,如本答案中所述。

Prefork MPM uses multiple child processes with one thread each and
each process handles one connection at a time.

Worker MPM uses
multiple child processes with many threads each. Each thread handles
one connection at a time.

显然,其他服务器可能采用其他方法,但我不知道这一点。

对于2和3,Web服务器和PHP部件在不同的进程中处理,Web服务器处理请求的方式以及应用程序(PHP部件)进一步处理请求的方式各不相同。例如:nginx可以使用异步非阻塞I/O处理请求,apache可以使用线程处理请求,但是fastcgi或cgi应用程序处理请求的方式与下面描述的不同。这两个方面,即Web服务器如何处理请求,以及如何处理PHP部分,对于PHP服务器的性能都很重要。

考虑到2,CGI协议使Web服务器和应用程序(PHP)相互独立,而CGI协议要求应用程序和Web服务器使用不同的进程进行处理,并且协议不促进同一进程的重用,这意味着处理每个请求需要一个新的进程。

考虑到3,fastcgi协议通过允许过程重用来克服cgi的限制。如果您检查IIS FastCGI链接FastCGI,通过提供一种机制来为许多请求反复重用单个进程,从而解决CGI固有的性能问题。

FastCGI maintains compatibility with non-thread-safe libraries by
providing a pool of reusable processes and ensuring that each process
handles only one request at a time.

也就是说,对于fastcgi,服务器似乎维护了一个进程池,它使用进程池来处理传入的客户机请求,因为进程池不需要线程安全检查,所以它提供了良好的性能。


我认为答案取决于Web服务器和CGI如何部署。

在我的公司中,我们使用nginx作为Web服务器,php fpm作为CGI,所以并发请求是由php fpm处理的,而不是线程。

我们配置最大进程数,每个请求都由一个PHP进程处理,如果有更多的请求(大于最大进程数)出现,它们就会等待。

所以,我相信PHP本身可以支持所有这些功能,但是如何使用它取决于具体情况。