如何让Apache运行PHP页面

11

想象一下,在http://server/page.php上有一个PHP页面。

客户端从浏览器同时向服务器发送了100个请求以获取该页面。

那么,服务器会同时运行100个php.exe进程吗?

它是否会对page.php进行100次重新解释?


虽然这是一个好问题,但首先它似乎不适合在SO上讨论,其次似乎也没有现有的研究,因为谷歌搜索结果中都是这个问题。 - Hanky Panky
4个回答

11

答案高度可变,取决于服务器配置。

让我们先回答问题1:

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

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

其他Web服务器也会存在类似的变化。请注意,对于基于Unix/Linux的操作系统,在每个请求中运行单独的可执行文件并不一定是性能问题;操作系统的核心是设计成在许多情况下,任务可以由许多单独的可执行文件而不是一个单片机执行。

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

现在是第二个问题:

它是否重新解释page.php 100次?

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

然而,PHP提供了几种缓存解决方案,专门设计用于缓解这种情况。主要选项包括APC和Zend Cache,其中任何一个都可以作为标准模块安装。使用这些模块将意味着PHP缓存解释代码,因此可以更快地运行后续调用。

从即将发布的PHP 5.5版开始,Zend Cache将作为标准PHP安装的一部分。


很好的回答,+1。不过,我认为PHP将包括APC,而不是Zend Cache? - halfer
2
@halfer - 不是,他们选择了Zend。他们将其重命名为OpCache(即没有Zend名称),但它仍然是Zend缓存。去年Zend开源了它,特别是为了将其引入5.5版本。 - Spudley
啊,没错,维基百科上的信息已经过时了,我也是!谢谢。 - halfer

5

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

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

如果您没有安装像APC、XCache和eAccelerator之类的opcode缓存扩展,php.exe将重新解释page.php 100次。


3
你的英语非常棒! - Rich Bradshaw

2

这要看情况。

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

简短的回答是“差不多”。将生成一些Apache进程,解析并运行PHP代码。

如果想避免解析开销,可以使用一个opcode缓存。 APC(替代PHP缓存)是一个非常流行的缓存。它具有一些值得深入挖掘的不错特性,但只需安装它即可确保每个php页面仅被解析为opcode一次,而无需任何配置。

要更改生成多少个Apache服务,最有可能使用MPM Prefork。这让您决定如何处理多个用户的Apache。

对于一般建议,在我的经验中(小型站点,没有太多流量),安装APC是值得做的,对于其他所有内容,默认设置都还不错。


1
有很多答案。通常情况下,Apache会为每个进来的请求创建一个进程,因此可能会创建100个进程。但是,创建一个进程需要时间,所以可能在一个进程完成并死亡之后,仅过了一小段时间就会有其中的一个100个连接到来(因为在完全相同的时间内出现100个连接是非常罕见的,除非你是谷歌)。
然而,让我们想象一下,确实需要同时在内存中保存100个进程,但可用服务器RAM只有50个。在这种情况下,将提供50个连接,并且还有50个连接必须等待进程死亡并重新生成。因此,那些请求的随机一半将被延迟,但如果进程的创建-进程死亡序列仅花费了一小部分时间,它们不必等待太长时间。这就是为什么在提高服务器容量时,减少页面加载时间和增加RAM一样重要——进程完成得越快,新进程就能越快地接替它的位置。

顺便提一下,减少加载时间的一种方法是生成许多PHP进程并将它们保留在内存中。这是FastCGI的基础(或兼容的fcgid)。与为每个请求创建和销毁进程不同,一个进程会立即在内存中生成,并且会被重复使用多个请求。对于PHP,通常会配置它们在某些页面请求之后死掉(例如1000次),因为历史上PHP存在相当多的内存泄漏问题(进程被重复使用得越多,内存泄漏问题就越糟糕)。

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接