当前位置: 首页 > 知识库问答 >
问题:

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

毕泽宇
2023-03-14

我知道PHP支持处理多个并发连接,并且根据服务器的不同,它可以像这个答案中提到的那样进行配置

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

链接的答案说一个进程是分叉的,然后作者在评论中说是线程还是进程,这让人很困惑,如果请求是使用子进程、线程还是线程池提供的?

共有3个答案

汝岳
2023-03-14

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

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

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

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

周苑博
2023-03-14

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

重要的是要考虑PHP服务器如何被设置为能够洞察它。要自行设置服务器和PHP,可能有三种可能性:

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

2)CGI

3)FastCGI

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

对于模块,Apachemod_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的情况下,服务器似乎维护一个进程池,并使用该进程池来处理传入的客户端请求,并且由于该进程池不需要线程安全检查,因此它提供了良好的性能

宋畅
2023-03-14

据我所知,每个网络服务器都有自己的处理多堆同时请求的方式。通常Apache2会为每个新请求分叉一个子进程。但是您可以按照链接的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中什么是线程安全或非线程安全?

 类似资料:
  • 我知道子进程是进程,而不是线程。我使用了错误的语义,因为大多数人在谈到“多线程”时都知道您的意图。所以我会把它保留在标题中。 想象一下这样一个场景:使用一个自定义函数或模块,您连续有多个类似和复杂的事情要做。使用所有可用的核心/线程(例如8/16)非常有意义,这就是的目的。 理想情况下,您需要多个同时工作的人员,并向一个控制器发送/从一个控制器发送/回调消息。 node cpool、fork po

  • 我想同时向一个webservice发送webservice调用。最多应有20个并行请求等待webservice响应。任何其他请求都应该等待它们完成。 如果一个用户向我发送一个请求,这通常会导致向目标服务器发送5个并行请求。因此,我一次最多可以服务20/5=4个用户。其他人将不得不等待,这很好。或者被高负荷拒绝。 问题:我应该使用哪个线程池,以及如何配置它? 我读了上面的内容如下:主池可以向网络服务

  • 问题内容: 在我们的软件中,我们广泛使用MDC来跟踪Web请求的内容,例如会话ID和用户名。在原始线程中运行时,这可以正常工作。但是,有很多事情需要在后台处理。为此,我们使用java.concurrent.ThreadPoolExecutor和java.util.Timer类以及一些自卷式异步执行服务。所有这些服务都管理自己的线程池。 这是Logback手册关于在这样的环境中使用MDC的内容: 映

  • 我需要创建一个并行执行多个操作的应用程序。我曾考虑过使用线程或线程池,但我以前从未使用过,所以我发现这相当困难。Thread应按以下方式工作: 所有系统应同时运行。你认为我应该如何实现这一点?

  • 问题内容: 有人可以解释什么是每个请求线程和每个连接线程吗?servlet使用哪种模型?如何分配线程来处理HTTP请求?是线程/请求还是连接? 假设我要在自己的方法中异步执行耗时的任务,那么我将使用Java执行程序启动一个新线程,以便在单独的线程中进行冗长的计算并立即发送响应。 现在,这是否可以确保我释放了正在处理我的线程,或者由于子线程仍在运行而仍在使用它? 问题答案: 每个请求意味着在发出HT

  • 本文向大家介绍C#线程处理系列之线程池中的I/O线程,包括了C#线程处理系列之线程池中的I/O线程的使用技巧和注意事项,需要的朋友参考一下 一、I/O线程实现对文件的异步  1.1  I/O线程介绍: 对于线程所执行的任务来说,可以把线程分为两种类型:工作者线程和I/O线程。 工作者线程用来完成一些计算的任务,在任务执行的过程中,需要CPU不间断地处理,所以,在工作者线程的执行过程中,CPU和线程