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

pra*_*sun 29 php concurrency child-process threadpool

我知道PHP支持处理多个并发连接,并且根据服务器,它可以按照本答案中的说明进行配置

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

链接的答案说的过程分叉,然后笔者在评述中说的线程或进程,这使得它混乱,如果要求使用儿童进程,线程或线程池提供服务?

jan*_*kal 21

据我所知,每个网络服务器都有自己的处理多重同声请求.通常Apache2 schould为每个新请求分叉子进程.但是,您可以按照链接的StackOverflow答案中提到的方式配置此行为.

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

Apache2可能是一个非常好的网络服务器,但是当你想在生产中使用它时,你需要更多的负载平衡.但是,当具有多个短持久连接或甚至根本不改变(或使用缓存)的文档时,它也具有良好的能力.

Nginx非常好,如果你期望很多持久的连接,在某种程度上长的处理时间.那么你不需要那么多的负载平衡.

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

资料来源:

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

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

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


pra*_*sun 5

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

重要的是要考虑如何设置 PHP 服务器才能深入了解它。 对于自己设置服务器和 PHP,可能有三种可能性:

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

2) 电脑动画

3) FastCGI

将案例#1 PHP 视为模块,在这种情况下,该模块与 Web 服务器本身集成在一起,现在它将球完全放在 Web 服务器上,它如何在分叉过程、使用线程、线程池等方面处理请求。

对于模块,Apache mod_php 似乎非常常用,Apache 本身使用本答案中提到的两种模型中的进程和线程来处理请求

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

Worker 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 的限制。如果您检查IIS FastCGI 链接, FastCGI 通过提供一种机制来为许多请求反复重用单个进程,从而解决了 CGI 中固有的性能问题。

FastCGI 通过提供可重用进程池并确保每个进程一次仅处理一个请求来保持与非线程安全库的兼容性。

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


Fis*_*tyn 5

我认为答案取决于Web服务器和CGI的部署方式。

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

我们配置最大进程数,每个请求由单个php进程处理,如果有更多请求(大于最大进程数)到来,它们将等待。

因此,我相信PHP本身可以支持所有这些,但是如何使用它取决于。