apache mpms和php概述

当设置一个Apache + PHP服务器来运行你的PHP应用程序时,有许多配置参数需要处理。 最重要的是php服务器Api(server api:sapi),它决定了Apache将如何运行PHP脚本。 除了php sapi之外,另一个重要的选择是apache mpm(多处理模块)。 mpms决定了apache如何处理一般的请求。

mpms和sapis有多种选择,每种都有自己的优点和缺点。 某些配置易于设置和管理,但性能较差,而有些则性能较高,但难以设置和维护。 由于可用的服务器种类繁多,通常很难决定选择哪一个。

mpms有prefork,worker,itk等等。在php sapi那边有3个基本选项,分别是mod_php,cgi和fastcgi。 除了这些之外,还有更多的组件可以在apache中使用,比如suphp,suexec,它可以修改标准sapis的行为。

[apache <=> some mpm] <=> some sapi <=> php interpreter/process

当决定使用那种具体的配置时,有很多事情需要考虑。

1、服务器有多少资源。 使用有限的内存和CPU能够满足需要。
2、需要什么安全选项。 如果我们通过apache vhosts在同一台服务器上建立多个网站/域名,那么我们需要在每个域中运行php scipts,使用它自己独立的UID /用户来获得正确的目录访问权限。
3、需要多少性能。 网站上的流量是高还是低?

有时候这个决定也会受到所需维护的容易性的影响。 有些系统管理员可能不希望有一个复杂的系统,从长远来看很难维护,并且可能愿意选择一个更易于配置并具有像Cpanel或Directadmin之类的GUI工具的备用配置。

Apache MPM

首先要了解的是apache mpms。 MPM或多处理模块是处理传入请求的apache代码的一部分。 所以不同的mpms处理请求的方式不同。 要注意的是,虽然这些被称为模块,但它们不像可加载模块可以加载多个。 而是一个mpm运行在Apache二进制文件里面。 所以一次只能安装1个mpm,而且你至少要安装1个mpm。(更多关于多处理模块资料)

1、mpm Prefork

这是apache带有的最老,最基本的mpm形式,并且与任何类型的php服务器api兼容。
官方描述

A single control process is responsible for launching child processes which listen for connections and serve them when they arrive. Apache always tries to maintain several spare or idle server processes, which stand ready to serve incoming requests. In this way, clients do not need to wait for a new child processes to be forked before their requests can be served.

prefork用单独的子进程来处理不同的请求,进程之间是彼此独立的,这也使其成为最稳定的MPM之一。但是由于每一个请求都会产生一个新的进程,导致系统资源(尤其是内存)消耗的很快,一旦并发量较大的时候,大量的Apache进程会占用巨大的内存空间。 Prefork MPM在所有情况下都很安全,对运行非线程安全(non-thread-safe)模式的软件如PHP,它是唯一的安全选择。

2、mpm Worker

mpm Worker解决了prefork的局限性。 它创建了像prefork这样的多个进程,但是也在每个进程内创建了多个线程。 每个线程都可以处理一个请求。 现在线程共享相同的资源,这个MPM是资源友好的。 事实上这也是所有情况下推荐使用的mpm,除非你被迫使用mod_php。MPM Worker 基于线程模式,具有内存消耗低(对繁忙的服务很重要)、扩展性在某些特定应用情况下比Prefork更好等优点。在这个模式下,采用的进程和线程混合的形式处理请求。由于使用线程来处理,所以可以处理相对海量的请求,而系统资源的开销要小于基于进程的Prefork模式。

官方描述

A single control process (the parent) is responsible for launching child processes. Each child process creates a fixed number of server threads as specified in the ThreadsPerChild directive, as well as a listener thread which listens for connections and passes them to a server thread for processing when they arrive.
Mpm worker可以用于任何PHP sapi 像cgi,suphp,fastcgi,fpm(modphp除外)。有许多php扩展不是线程安全的,因此如果你试图用mod_php运行mpm worker,那么apache服务器会不时崩溃。 在Ubuntu上,例如安装modphp会自动删除mpm worker。

除了常用的prefork和worker还有其他的mpm,这里就不详细列出来了。

PHP server api

PHP 服务器的API决定了如何将自己连接到PHP解释器来执行PHP文件并获得输出。 和mpm一样,这里也有很多选择。有可用于apache的模块或组件,可以按需加载以提供各种功能。 例如mod_php是授权apache直接加载php解释器并运行php代码的模块。 mod_fastcgi模块使apache能够与fastcgi协议进行通信,以支持fastcgi应用程序。 例如,php-cgi二进制文件是启用fastcgi的。

1、 Mod PHP (a.k.a Apache 2.0 Handler or DSO)

这是最简单的PHP处理程序,并在默认情况下在Ubuntu系统上安装,例如,当您尝试从突触安装PHP。

$ sudo apt-get install apache2 php5

Mod PHP是一个Apache模块,直接加载PHP解释器,并在Apache内运行PHP代码。 它不会像使用php-cgi二进制文件那样将php加载为外部进程。 所以php解释器和apache进程成为一体。 新fork出的apache进程,都有自己的php解释器。
控制的流程就像这样

apache process (php interpreter) <==> execute php code

基本上apache直接变成了一个php解释器。Mod PHP只适用于非线程mpm像prefork。由于这个Apache的线程功能完全丢失。

Prefork的速度很慢,因为每一个请求都会产生一个新的进程。而且,每个进程都有一个“自带”php解释器,即使它正在为JavaScript / css / images等静态内容提供请求。这使得它非常低效。

PHP脚本将只运行一个用户,如“www-data”或“nobody”。所以,如果你有多个网站,那么它不可能使每个虚拟主机运行自己的独立用户/ uid。 1个虚拟主机中的脚本可以读取其他虚拟主机的文件。

唯一例外的情况下,mod_php可以与每个虚拟主机使用不同的uid,使用mpm-itk,它将在apache内实现用户/ uid切换。可以是有用的,但有一个限制,它不重用一个进程,并产生一个新的进程,每一个请求使得它比prefork更糟糕。

2、 CGI - Common Gateway Interface

这是一个中立的协议,可以用来连接任何网络服务器与任何语言解释器。 我们在这里连接Apache和Php。 它在apache内部是通过mod_cgi实现的。

通过cgi,php的执行从apache环境中分离出来。 Apache将改为调用一个外部程序,如“php-cgi.exe”,通过输入和输出。 所以需要创建一个单独的php进程。

Apache (any mpm) <=========> /usr/bin/php-cgi binary [multiple instances per mpm process/thread]

参考资料

[1] http://www.binarytides.com/apache-mpm-php-server-api/
[2] http://wiki.apache.org/httpd/php
[3] http://www.brandonturner.net/blog/2009/07/fastcgi_with_php_opcode_cache/

猜你喜欢

转载自blog.csdn.net/hjxzb/article/details/79216364