apache两种工作模式详解 |
|
来源: ChinaUnix博客 日期: 2008.06.21 13:09 (共有条评论) 我要评论 |
|
[url=http://www.sudu.cn/web/host.php][/url] 刚接触这两个配置时很迷糊,全部开启或全部注释没有几多变化。今天搜索到这么一篇讲得还不错的文章,看了几篇,还是不能完全记住,做一个收藏。 空闲子进程:是指没有正在处理请求的子进程。 1、prefork.c模块(一个非线程型的、预派生的MPM) prefork MPM 使用多个子进程,每个子进程只有一个线程。每个进程在某个确定的时间只能维持一个连接。在大多数平台上,Prefork MPM在效率上要比Worker MPM要高,但是内存使用大得多。prefork的无线程设计在某些情况下将比worker更有优势:他能够使用那些没有处理好线程安全的第三方模块,并 且对于那些线程调试困难的平台而言,他也更容易调试一些。 ServerLimit 20000 StartServers 5 MinSpareServers 5 MaxSpareServers 10 MaxClients 1000 MaxRequestsPerChild 0 ServerLimit 2000 //默认的MaxClient最大是256个线程,假如想配置更大的值,就的加上ServerLimit这个参数。20000是ServerLimit这个参数的最大值。假如需要更大,则必须编译apache,此前都是无需重新编译Apache。 生效前提:必须放在其他指令的前面 StartServers 5 //指定服务器启动时建立的子进程数量,prefork默认为5。 MinSpareServers 5 //指定空闲子进程的最小数量,默认为5。假如当前空闲子进程数少于MinSpareServers ,那么Apache将以最大每秒一个的速度产生新的子进程。此参数不要设的太大。 MaxSpareServers 10 //配置空闲子进程的最大数量,默认为10。假如当前有超过MaxSpareServers数量 的空闲子进程,那么父进程将杀死多余的子进程。此参数不要 设的太大。假如您将该指令的值配置为比MinSpareServers小,Apache将会自动将其修改成"MinSpareServers+1"。 MaxClients 256 //限定同一时间客户端最大接入请求的数量(单个进程并发线程数),默认为256。任何超过MaxClients限制的请求都将进入等候队列,一旦一个链接被释放,队列中的请求将得到服务。要增大这个值,您必须同时增大ServerLimit 。 MaxRequestsPerChild 10000 //每个子进程在其生存期内允许伺服的最大请求数量,默认为10000.到达MaxRequestsPerChild的限制后,子进程将会结束。假如MaxRequestsPerChild为"0",子进程将永远不会结束。 将MaxRequestsPerChild配置成非零值有两个好处: 1.能够防止(偶然的)内存泄漏无限进行,从而耗尽内存。 2.给进程一个有限寿命,从而有助于当服务器负载减轻的时候减少活动进程的数量。 工作方式: 一个单独的控制进程(父进程)负责产生子进程,这些子进程用于监听请求并作出应答。Apache总是试图保持一些备用的 (spare)或是空闲的子进程 用于迎接即将到来的请求。这样客户端就无需在得到服务前等候子进程的产生。在Unix系统中,父进程通常以root身份运行以便邦定80端口,而 Apache产生的子进程通常以一个低特权的用户运行。User和Group指令用于配置子进程的低特权用户。运行子进程的用户必须要对他所服务的内容有 读取的权限,但是对服务内容之外的其他资源必须拥有尽可能少的权限。 2、worker.c模块(支持混合的多线程多进程的多路处理模块) worker MPM 使用多个子进程,每个子进程有多个线程。每个线程在某个确定的时间只能维持一个连接。通常来说,在一个高流量的HTTP服务器上,Worker MPM是个比较好的选择,因为Worker MPM的内存使用比Prefork MPM要低得多。但worker MPM也由不完善的地方,假如一个线程崩溃,整个进程就会连同其任何线程一起"死掉".由于线程共享内存空间,所以一个程式在运行时必须被系统识别为"每 个线程都是安全的"。 ServerLimit 50 ThreadLimit 200 StartServers 5 MaxClients 5000 MinSpareThreads 25 MaxSpareThreads 500 ThreadsPerChild 100 MaxRequestsPerChild 0 ServerLimit 16 //服务器允许配置的进程数上限。这个指令和ThreadLimit结合使用配置了MaxClients最大允许配置的数值。任何在重启期间对这个指令的改变都将被忽略,但对MaxClients的修改却会生效。 ThreadLimit 64 //每个子进程可配置的线程数上限。这个指令配置了每个子进程可配置的线程数ThreadsPerChild上限。任何在重启期间对这个指令的改变都将被忽略,但对ThreadsPerChild的修改却会生效。默认值是"64". StartServers 3 //服务器启动时建立的子进程数,默认值是"3"。 MinSpareThreads 75 //最小空闲线程数,默认值是"75"。这个MPM将基于整个服务器监控空闲线程数。假如服务器中总的空闲线程数太少,子进程将产生新的空闲线程。 MaxSpareThreads 250 //配置最大空闲线程数。默认值是"250"。这个MPM将基于整个服务器监控空闲线程数。假如服 务器中总的空闲线程数太多,子进程将杀死多余的空闲线 程。MaxSpareThreads的取值范围是有限制的。Apache将按照如下限制自动修正您配置的值:worker需要其大于等于 MinSpareThreads加上ThreadsPerChild的和 MaxClients 400 //允许同时伺服的最大接入请求数量(最大线程数量)。任何超过MaxClients限制的请求都将进入等候 队列。默认值是"400",16 (ServerLimit)乘以25(ThreadsPerChild)的结果。因此要增加MaxClients的时候,您必须同时增加 ServerLimit的值。 ThreadsPerChild 25 //每个子进程建立的常驻的执行线程数。默认值是25。子进程在启动时建立这些线程后就不再建立新的线程了。 MaxRequestsPerChild 0 //配置每个子进程在其生存期内允许伺服的最大请求数量。到达MaxRequestsPerChild的限制后,子进程将会结束。假如MaxRequestsPerChild为"0",子进程将永远不会结束。 将MaxRequestsPerChild配置成非零值有两个好处: 1.能够防止(偶然的)内存泄漏无限进行,从而耗尽内存。 2.给进程一个有限寿命,从而有助于当服务器负载减轻的时候减少活动进程的数量。 注意 对于KeepAlive链接,只有第一个请求会被计数。事实上,他改变了每个子进程限制最大链接数量的行为。 工作方式: 每个进程能够拥有的线程数量是固定的。服务器会根据负载情况增加或减少进程数量。一个单独的控制进程(父进程)负责子进程的建 立。每个子进程能够建立 ThreadsPerChild数量的服务线程和一个监听线程,该监听线程监听接入请求并将其传递给服务线程处理和应答。Apache总是试图维持一个备 用(spare)或是空闲的服务线程池。这样,客户端无须等待新线程或新进程的建立即可得到处理。在Unix中,为了能够绑定80端口,父进程一般都是以 root身份启动,随后,Apache以较低权限的用户建立子进程和线程。User和Group指令用于配置Apache子进程的权限。虽然子进程必须对 其提供的内容拥有读权限,但应该尽可能给予他较少的特权。另外,除非使用了suexec ,否则,这些指令配置的权限将被CGI脚本所继承。 公式: ThreadLimit >= ThreadsPerChild MaxClients = MinSpareThreads+ThreadsPerChild 硬限制: ServerLimi和ThreadLimit这两个指令决定了活动子进程数量和每个子进程中线程数量的硬限制。要想改变这个硬限制必须完全停止服务器然后再启动服务器(直接重启是不行的)。 Apache在编译ServerLimit时内部有一个硬性的限制,您不能超越这个限制。 prefork MPM最大为"ServerLimit 200000" 其他MPM(包括work MPM)最大为"ServerLimit 20000 Apache在编译ThreadLimit时内部有一个硬性的限制,您不能超越这个限制。 mpm_winnt是"ThreadLimit 15000" 其他MPM(包括work prefork)为"ThreadLimit 20000 注意 使用ServerLimit和ThreadLimit时要特别当心。假如将ServerLimit和ThreadLimit配置成一个高出实际需要许多的值,将会有过多的共享内存被分配。当配置成超过系统的处理能力,Apache可能无法启动,或系统将变得不稳定。 |
PHP
在Apache中两种工作方式(CGI模式、Apache模块DLL)
2010-07-21 15:07
PHP
在Apache中两种工作方式(CGI模式、Apache模块DLL)
PHP
在Apache中有两种工作方式:一种是 使用 CGI 可执行程序,另一种是适用 Apache 模块的 DLL。
这两种工作方式的安装:
1. CGI
方式
PHP
在 Apache 2.0 中的 CGI 方式
ScriptAlias /php/ "c:/php/"
AddType application/x-httpd-php .php
#
对 PHP 4 用这行
Action application/x-httpd-php "/php/php.exe"
#
对 PHP 5 用这行
Action application/x-httpd-php "/php/php-cgi.exe"
2. APACHE Module
方式
PHP
在 Apache 2.0 中的模块方式
#
对 PHP 4 用这两行:
LoadModule php4_module "c:/php/php4apache2.dll"
# 别忘了从 sapi 目录中把 php4apache2.dll 拷贝出来!
AddType application/x-httpd-php .php
#
对 PHP 5 用这两行:
LoadModule php5_module "c:/php/php5apache2.dll"
AddType application/x-httpd-php .php
#
配置 php.ini 的路径
PHPIniDir "C:/php"
这两种工作方式的区别:
在CGI模式下,如果客户机请求一个php文件,Web服务器就调用php.exe去解释这个文件,然后再把解释的结果以网页的形式返回给客户机;
而在模块化(DLL)中,PHP是与Web服务器一起启动并运行的。所以从某种角度上来说,以apache模块方式安装的PHP4有着比CGI模式更好的安全性以及更好的执行效率和速度。
一、FastCGI是什么?
FastCGI是语言无关的、可伸缩架构的CGI开放扩展,其主要行为是将CGI解释器进程保持在内存中并因此获得较高的性能。众所周知,CGI解释器的反复加载是CGI性能低下的主要原因,如果CGI解释器保持在内存中并接受FastCGI进程管理器调度,则可以提供良好的性能、伸缩性、Fail-Over特性等等。
FastCGI的官方站点在http://www.fastcgi.com
FastCGI的工作原理是:
1、Web Server 启动时载入FastCGI进程管理器(IIS ISAPI或Apache Module);
2、FastCGI进程管理器自身初始化,启动多个CGI解释器进程 (在任务管理器中可见多个php-cgi.exe)并等待来自Web Server的连接。
3、当客户端请求到达Web Server时,FastCGI进程管理器选择并连接到一个CGI解释器。Web server将CGI环境变量和标准输入发送到FastCGI子进程php-cgi.exe。
4、FastCGI子进程完成处理后将标准输出和错误信息从同一连接返回Web Server。当FastCGI子进程关闭连接时,请求便告处理完成。FastCGI子进程接着等待并处理来自FastCGI进程管理器(运行在 WebServer中)的下一个连接。 在正常的CGI模式中,php-cgi.exe在此便退出了。
在上述情况中,你可以想象 CGI通常有多慢。每一个Web请求PHP都必须重新解析php.ini、重新载入全部dll扩展并重初始化全部数据结构。使用FastCGI,所有这些都只在进程启动时发生一次。一个额外的好处是,持续数据库连接(Persistent database connection)可以工作。
二、为什么要使用FastCGI,而不是多线程CGI解释器?
这可能出于多方面的考虑,例如:
1、你无论如何也不能在windows平台上稳定的使用多线程CGI解释器,无论是IIS ISAPI方式还是APACHE Module方式,它们总是运行一段时间就崩溃了。奇怪么?但是确实存在这样的情况!
当然,也有很多时候你能够稳定的使用多线程CGI解释器,但是,你有可能发现网页有时候会出现错误,无论如何也找不到原因,而换用FastCGI方式时这种错误的概率会大大的降低。我也不清楚这是为什么,我想独立地址空间的CGI解释器可能终究比共享地址空间的形式来得稳定一点点。
2、性能!性能?可能么,难道FastCGI比多线程CGI解释器更快?但有时候确实是这样,只有测试一下你的网站,才能最后下结论。原因嘛,我觉得很难讲,但有资料说在Zend WinEnabler的时代,Zend原来也是建议在Windows平台下使用FastCGI而不是IIS ISAPI或Apache Module,不过现在Zend已经不做这个产品了。
三、不使用FastCGI的理由
1、多进程比多线程消耗更多的服务器内存,php-cgi.exe解释器每进程消耗7至25兆内存,将这个数字乘以50或100试试。
2、性能。确实有时候多线程CGI解释器更快,呵呵,而且有时候,它也很稳定。
3、CGI?听起来就很土,呵呵
四、IIS FastCGI配置方法
1、首先确定你已正确安装了PHP 4.3.x及更新的版本。早期版本的PHP并未默认加入FastCGI支持,如果你想在早期版本中工作,需要重新编译它。我们假设PHP安装在c:\php,支持FastFCGI的可执行文件名是php-cgi.exe。
注意:建议在Php.ini中关闭cgi.force_redirect,启用fastcgi.impersonate,启用cgi.rfc2616_header
2、下载http://www.caraveo.com/fastcgi/fastcgi-0.6.zip并将其中的isapi_fcgi.dll解压缩到c:\php目录下(不是必须在此目录,这里只是叙述方便)。
3、使用regedit.exe建立如下注册表项:
HKEY_LOCAL_MACHINE:Software\FASTCGI\.php (必需)
4、在此项下建立如下键值:
字符串类型:AppPath,值为c:\php\php-cgi.exe (必需)
字符串类型:BindPath,值为php-fcgi (必需)
以下是可选配置键值:
DWORD类型:StartServers,启动时默认启动的解释器个数,默认值5
DWORD类型:MaxServers,最大解释器个数,默认25
DWORD类型:IncrementServers,当解释器不够用时增量个数,默认2
DWORD类型:Timeout,增量解释器(超出StartServers数目的)存活时间,默认600(秒)
DWORD类型:ThreadPoolSize,线程池大小,仅IIS下有效,默认10
DWORD类型:Impersonate,仅IIS有效,如果为1,使用IIS安全标志,为0则关闭此特性。不要关闭它除非你不担心安全问题。默认1
DWORD类型:MaxPostData,Post数据预读Byte限制,默认0
DWORD类型:BypassAuth,仅IIS有效,如果为1并且isapi_fcgi.dll被配置为IIS Filter,同时IIS被配置为使用BASIC Authentication,这将强制所有认证请求使用IIS匿名用户。这一选项的目的是允许脚本实现自己的安全机制。默认0
BINARY类型:CustomVars,附加环境变量值,新行分隔,Null结束
5、如果是IIS6,添加一个Web服务扩展指向c:\php\isapi_fcgi.dll,并允许。应用程序池中的“最大工作进程数”请保持为1。
6、添加应用程序扩展映射关系:
1). 在Internet信息服务管理器中,选择网站或应用程序的根目录。
2). 打开目录属性页(右键选择“属性”),再选择“主目录”。
3). 点击“配置”按钮,选择“映射”Tab页。
4). 点击“添加...”,在“可执行文件”设为: c:\php\isapi_fcgi.dll,扩展名设为.php,一定要选择“确认文件是否存在”,然后“确定”保存设置。
5). 再同样添加对.php3或.phtml扩展名的支持(可选)。
6). 保存设定并重新启动IIS。
7、测试一下,同时请求多个Web页面,然后察看任务管理器中的进程,页面完成后php-cgi.exe进程持续运行并不退出。
五、Apache配置方法
1、首先确定你已正确安装了PHP 4.3.x及更新的版本。早期版本的PHP并未默认加入FastCGI支持,如果你想在早期版本中工作,需要重新编译它。我们假设PHP安装在c:\php,支持FastFCGI的可执行文件名是php-cgi.exe。
注意:建议在Php.ini中打开cgi.force_redirect,关闭fastcgi.impersonate,关闭cgi.rfc2616_headers。
2、下载http://www.fastcgi.com/dist/mod_fastcgi-2.4.2-AP20.dll,放到Apache 2.x的Modules目录中。
3、确定Apache 2.x在CGI方式下可以正常运行PHP。httpd.conf中存在如下几行:
ScriptAlias /php/ "c:/php/"
Action application/x-httpd-php "/php/php-cgi.exe"
SetEnv PHPRC "C:/php"
AddType application/x-httpd-php .php
4、在httpd.conf中添加:
LoadModule fastcgi_module modules/mod_fastcgi-2.4.2-AP20.dll
# 说明:此处的 -processes 3 表示启动三个 php-cgi.exe 进程,
# 关于 FastCgiServer 的详细参数请参考 FastCGI 文档。
FastCgiServer "c:/php/php-cgi.exe" -processes 3
5、重新启动Apache,测试同上。
六、高级配置
设想这样一种场景,你的服务器上同时跑Apache 2和IIS 6,两个Web服务器都跑php应用。那么,有如下三种可能:
A、php使用iis isapi和apache module安装,均为多线程方式运行。这个和FastCGI没有关系。
B、其中一个服务器使用FastCGI方式,另一个使用多线程方式。这个能运行正常。
C、两个均使用FastCGI方式,这个往往不正常。一般表现为:
两个服务器各自启动一些php-cgi.exe进程,然后服务器之一不解释php页面,或者隔一会儿就派生新的php-cgi.exe进程(可怕呀)。
为什么呢?我想大概是因为上面使用的两个东西(iis isapi和apache module)的作者大概并没有想过要和对方同时使用吧,呵呵。想了想,Apache 2和IIS 6如果可以共用一批php-cgi.exe解释器就好了,既不浪费内存,估计也不会有调度问题了。
经过研究和测试证明,这个想法是可行的。但是,由于Shane Caraveo并未在ISAPI DLL中提供使用外置FastCGI服务的功能,因此在此场景中只能是由IIS负责启动和管理php-cgi.exe,然后配置Apache去使用这些受 IIS管理的php-cgi.exe进程。
配置方法:
1、按上述四中的方法配置IIS FastCGI。
2、基本按上述五中的方法配置Apache FastCGI,五.4改为在httpd.conf中添加:
LoadModule fastcgi_module modules/mod_fastcgi-2.4.2-AP20.dll
# 使用外部FastCGI服务器,请参考 FastCGI 文档。
FastCgiExternalServer "c:/php/php-cgi.exe" -socket "php-fcgi"
注意:-socket参数后的值必须与HKEY_LOCAL_MACHINE:Software\FASTCGI\.php中BindPath的值一致,这样两个FastCGI进程管理器才会使用同一个命名管道连接php-cgi.exe。
注意:此配置中php-cgi.exe进程只受IIS中的FastCGI进程管理器管理, Apache的繁忙请求并不会使IIS中的FastCGI调度更多的php-cgi.exe进程。因此,在IIS中配置FastCGI时应当使 StartServers值足够大,以避免php解释器数量不足。同样带来的问题是,如果IIS关闭了,那么Apache就会找不到Php解释器了,这个要留心。
由此带来的一个问题是:此时的php.ini中cgi.force_redirect、fastcgi.impersonate、cgi.rfc2616_headers应该怎么设定呢?这个留给大家去思考吧……呵呵
另外一个可能遇到的问题是,IIS非常空闲,一段时间后由IIS启动的php-cgi.exe退出了,则apache就解释不了 Php了,怎么办呢?这时可以访问一下iis网站,php-cgi.exe就又起来了,晕哦。一个建议是使用IIS 6的进程池管理,在应用程序池中关掉“空闲超时”,并且,在“应用程序池标识”中将运行账号设定为与Apache服务启动账号一致。