Apache HTTP服务器被设计为一个强大的、灵活的能够在多种平台以及不同环境下工作的服务器。
不同的平台和不同的环境经常产生不同的需求,或是为了达到同样的最佳效果而采用不同的方法。
Apache凭借它的模块化设计很好的适应了大量不同的环境。
这一设计使得网站管理员能够在编译时和运行时凭借载入不同的模块来决定服务器的不同附加功能。

Apache2.0将这种模块化的设计延伸到了web服务器的基础功能上。
这个版本带有多路处理模块(MPM)的选择以处理网络端口绑定、
接受请求并指派子进程来处理这些请求。
比如,需要更好伸缩性的可以选择象worker或event这样线程化的MPM,
而需要更好的稳定性和兼容性以适应一些旧的软件可以用prefork 。

在Redhat Linux的主要版本as4上,apache版本为httpd-2.0.5x,
默认为prefork模式,主要是考虑到稳定性的原因。
要切换到worker模式,则需要登录到linux上,进行如下操作:

进入/usr/sbin目录
cd /usr/sbin

将当前的prefork模式启动文件改名
mv httpd httpd.prefork

将worker模式的启动文件改名
mv httpd.worker httpd

修改配置文件vim /etc/httpd/conf/httpd.conf
找到里边的如下一段,可适当修改负载等参数:

<IfModule worker.c>  
StartServers 2  
MaxClients 150  
MinSpareThreads 25  
MaxSpareThreads 75  
ThreadsPerChild 25  
MaxRequestsPerChild 0  
</IfModule>

重新启动服务
/etc/init.d/httpd restart

即可换成worker方式启动apache2

注意这里可能会遇到错误:

Apache is running a threaded MPM, but your PHP Module is not compiled to be threadsafe. You need to recompile PHP. Pre-configuration failed!  ``` 

解决方法是将/etc/httpd/conf.d/php.conf文件中的LoadModule开头的那行代码注释掉。  
--------------------------

注意:处于稳定性和安全性考虑,不建议更换apache2的运行方式,使用系统默认prefork即可  
另外很多php模块不能工作在worker模式下,例如redhat linux自带的php也不能支持线程安全  
所以最好不要切换工作模式。

2、worker.c模块(支持混合的多线程多进程的多路处理模块)  
worker MPM 使用多个子进程,每个子进程有多个线程。每个线程在某个确定的时间只能维持一个连接。通常来说,在一个高流量的HTTP服务器上,Worker MPM是个比较好的选择,因为Worker MPM的内存使用比Prefork MPM要低得多。但worker MPM也由不完善的地方,假如一个线程崩溃,整个进程就会连同其任何线程一起&#8221;死掉&#8221;.由于线程共享内存空间,所以一个程式在运行时必须被系统识别为&#8221;每 个线程都是安全的&#8221;。

ServerLimit   50
ThreadLimit   200
StartServers   5
MaxClients   5000
MinSpareThreads   25
MaxSpareThreads   500
ThreadsPerChild   100

###检查当前模式
MaxRequestsPerChild 0[root@test sbin]# apachectl -l
Compiled in modules:
core.c
worker.c
http_core.c
mod_so.c

#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
worker下:MaxSpareThreads>= MinSpareThreads+ThreadsPerChild
MaxClients=ServerLimit*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可能无法启动,或系统将变得不稳定。

* * *