如何在PHP中处理并发请求(使用线程、线程池或子进程)

如何在PHP中处理并发请求(使用线程、线程池或子进程),php,concurrency,threadpool,child-process,Php,Concurrency,Threadpool,Child Process,我知道PHP支持处理多个并发连接,根据服务器的不同,它可以按照本文所述进行配置 服务器是如何管理多个连接的?它是为每个请求派生一个子进程,还是使用线程处理,还是使用线程池处理 如果请求是使用子进程、线程或线程池来处理的,则说明一个进程是分叉的,然后作者在评论中说是线程或进程,这让人感到困惑。正如我所知,每个Web服务器都有自己的处理多文件同时请求的方式。 通常,Apache2会为每个新请求派生一个子进程。但是您可以按照您的答案中提到的方式配置此行为 例如,Nginx在一个线程中获取每个请求(像N

我知道PHP支持处理多个并发连接,根据服务器的不同,它可以按照本文所述进行配置

服务器是如何管理多个连接的?它是为每个请求派生一个子进程,还是使用线程处理,还是使用线程池处理


如果请求是使用子进程、线程或线程池来处理的,则说明一个进程是分叉的,然后作者在评论中说是线程或进程,这让人感到困惑。

正如我所知,每个Web服务器都有自己的处理多文件同时请求的方式。 通常,Apache2会为每个新请求派生一个子进程。但是您可以按照您的答案中提到的方式配置此行为

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

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

Nginx非常好,如果您希望有很多持久的连接,但处理时间却很长。你不需要那么多的负载平衡

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

资料来源:


我建议你也看看:

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

重要的是要考虑PHP服务器是如何建立它的洞察力的。为了建立服务器和PHP,可以有三种可能性:

1) 使用PHP作为模块(对于许多服务器,PHP有一个直接的模块接口(也称为SAPI))

2) CGI

3) 快速CGI

将Case#1 PHP视为模块,在本例中,该模块与web服务器本身集成,现在,它将完全取决于web服务器如何处理分叉进程、使用线程、线程池等方面的请求

对于模块,apachemod_php似乎非常常用,而Apache本身使用两种模型中的进程和线程来处理请求,如本文所述

Prefork MPM使用多个子进程,每个子进程有一个线程,并且 每个进程一次处理一个连接

工人MPM使用 多个子进程,每个子进程有多个线程。每个线程处理 一次一个连接

显然,其他服务器可能会采取其他方法,但我不知道有相同的方法

对于#2和#3,web服务器和PHP部分在不同的进程中处理,web服务器如何处理请求以及应用程序如何进一步处理请求(PHP部分)也各不相同。例如:NGINX可以使用异步非阻塞I/O处理请求,Apache可以使用线程处理请求,但是,FastCGI或CGI应用程序如何处理请求是一个不同的方面,如下所述。web服务器如何处理请求以及PHP部件如何处理这两个方面对PHP服务器的性能都很重要

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

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

FastCGI通过以下方式保持与非线程安全库的兼容性 提供一个可重用流程池,并确保每个流程 一次只处理一个请求


也就是说,在FastCGI的情况下,服务器似乎维护一个进程池,它使用进程池来处理传入的客户端请求,并且由于进程池不需要线程安全检查,因此它提供了良好的性能。

我认为答案取决于web服务器和cgi的部署方式

在我的公司,我们使用Nginx作为web服务器,使用php-fpm作为cgi,因此并发请求由php-fpm作为进程处理,而不是线程

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


因此,我相信PHP本身可以支持所有这些,但如何使用它,这取决于。PHP不处理请求。web服务器可以

对于Apache HTTP服务器,最流行的是“mod_php”。这个模块实际上是PHP本身,但编译为web服务器的一个模块,因此它被直接装入其中

由于使用mod_php,如果Apache打算使用其Worker MPM(即使用线程)处理并发性,那么php将直接加载到Apache中

对于
nginx
PHP完全在web服务器之外,有多个PHP进程

它有时让您可以选择使用
非线程安全的
线程安全的
PHP

但是setlocale()函数(如果受支持)实际上是修改操作系统进程状态的,它不是线程安全的


当你不确定遗留代码是如何工作的时候,你应该记住这一点。

[,我想这就是你想要的。对于FastCGI,我并不完全理解,因为FastCGI是作为一个不同的应用程序进程运行的。如何管理线程/进程来处理传入的请求?我的理解是,对于nginx,它本身不会产生错误