11

Imagine there is a PHP page on http://server/page.php.

Client(s) send 100 requests from browser to the server for that page simultaneously.

Does the server run 100 separate processes of php.exe simultaneously?

Does it re-interpret the page.php 100 times?

4

4 回答 4

11

根据服务器配置,答案是高度可变的。

我们先回答问题1:

服务器是否同时运行 100 个单独的 php.exe 进程?

这取决于 PHP 的安装方式。如果 PHP 是通过 CGI 运行的,那么答案是“是的,每个请求都调用一个单独的 PHP 实例”。如果它是通过 Apache 模块运行的,那么答案是“不,每个请求都会在 Apache 可执行文件中启动一个新的 PHP 线程”。

其他 Web 服务器也将存在类似的变化。请注意,对于基于 Unix/Linux 的操作系统,为每个请求运行单独的可执行文件副本不一定对性能不利;操作系统的核心是这样设计的,在许多情况下,任务最好由多个单独的可执行文件完成,而不是一个单一的可执行文件。

但是,无论您如何处理,同时处理大量请求都会耗尽您的服务器资源并导致用户超时和错误。这就是为什么让您的 PHP 程序尽快完成运行很重要的原因。不要编写运行缓慢的用于 Web 消费的 PHP 程序;如果您可能有很多流量,您需要像测试功能一样测试性能。让您的程序快速退出将大大降低同时请求大量的可能性,这显然会对您网站的性能产生重大影响。

现在你的第二个问题:

它会重新解释 page.php 100 次吗?

对于标准的 PHP 安装,这里的答案是“是的,它确实会影响性能”。

但是,PHP 提供了几种专门用于缓解这种情况的缓存解决方案。主要选项是 APC 和 Zend Cache,它们都可以作为标准模块安装。使用这些模块意味着 PHP 会缓存解释的代码,因此它可以在后续调用中运行得更快。

Zend Cache 将作为即将发布的 PHP 5.5 版本的标准 PHP 安装的一部分包含在内。

于 2013-06-01T16:08:33.000 回答
5

Apache2 有多种不同的工作模式。

在“prefork”(最常用的)模式下,Apache 会为每个请求创建进程,每个进程都会运行一个自己的 php.exe。配置文件将分配最大连接数(MaxClients在 httpd.conf 中),Apache 只会创建 MaxClients。这是为了防止内存耗尽。更多请求排队,等待前一个请求完成。

如果不安装 APC、XCache、eAccelerator 等操作码缓存扩展,php.exe 将重新解释 page.php 100 次。

于 2013-06-01T16:02:00.640 回答
2

这取决于。

有不同的设置方式,事情可能会变得相当复杂。

简短的回答是“或多或少”。将产生多个 apache 进程,解析并运行 PHP 代码。

如果您想避免解析开销,请使用操作码缓存。APC(Alternative PHP Cache)是一种非常流行的缓存。它有许多值得深入研究的简洁功能,但除了安装它之外没有任何配置,它将确保每个 php 页面只解析一次操作码。

要更改生成的 apache 服务的数量,您很可能会使用MPM Prefork。这使您可以决定是否希望 Apache 如何处理多个用户。

对于一般建议,根据我的经验(小型站点,不是大量流量),安装 APC 是值得的,对于其他一切,默认值都不算太差。

于 2013-06-01T16:01:53.273 回答
1

对此有很多答案。一般来说,Apache 会为传入的请求创建一个进程,因此可能会创建 100 个进程。然而,一个进程需要时间来创建,所以当一个进程完成并终止时,这 100 个连接中的一个可能会在几分之一秒后出现(因为在同一时间有 100 个连接确实非常罕见,除非你是谷歌)。

但是,让我们想象一下,确实需要同时在内存中保存 100 个进程,但可用服务器 RAM 中只有 50 个空间。在这种情况下,将提供 50 个连接,其中 50 个必须等待进程终止并重新生成。因此,这些请求的随机一半将被延迟,尽管如果进程创建-进程-die 序列只需要几分之一秒,它们就不必等待很长时间。这就是为什么在提高服务器容量时,减少页面加载时间与添加更多 RAM 一样重要 - 进程越早完成,新进程越早取代它。

顺便说一句,减少加载时间的一种方法是生成多个 PHP 进程并将它们保存在内存中。这是 FastCGI(或兼容的 fcgid)的基础。不是为每个请求创建和终止一个进程,而是立即在内存中生成一个进程并重新用于多个请求。对于 PHP,这些通常配置为在一定数量的页面请求(例如 1000 个)后终止,因为历史上 PHP 有相当多的内存泄漏(重用进程越多,内存泄漏越严重)。

您询问是否为每个请求重新解释页面。通常是的,但如果您还运行 PHP 加速器,则不会 - PHP 编译成的字节码被缓存和重用。因此,将 FastCGI 方法与加速器混合使用确实可以实现非常快速的服务器。标准 PHP 不附带加速器,但 Zend Cache计划包含在 PHP 核心中。

于 2013-06-01T16:00:31.723 回答