Apache的工作模式有:beos,event,worker,prefork,mpmt_os2,但最常用的有两种:prefork和worker。
prefork,是unix平台上默认MPM(MPM,Multi Processing Modules,多道处理模块。),使用多个子进程,每个子进程只有一个线程。每个进程在某个确定的时间只能维持一个连接,在大多数平台上,Prefork MPM在效率上要比Worker MPM要高,但是内存占用比较大。prefork的无线程设计在某些情况下将比worker更有优势:它可以使用那些没有处理好线程安全的第三方模块,并且对于那些线程调试困难的平台而言,它也更容易调试一些。
Prefork的工作原理是,控制进程在最初建立“StartServers”个子进程后,为了满足MinSpareServers设置的需要创建一个进程,等待一秒钟,继续创建两个,再等待一秒钟,继续创建四个......如此按指数级增加创建进程数,最大达到每秒32个,直到满足MinSpareServers设置为止。这就是预派生(prefork)的由来。这种模式可以不必在请求到来时再产生新的进程,从而减少系统开销以增加性能。
MaxSpareServers设置了最大的空闲进程数,如果空闲进程数大于这个值,Apache会自动kill掉一些多余进程。这个值不要设置得过大,但如果设的值比MinSpareServers小,Apache会自动将其调整为MinSpareServers+1.如果站点负载较大,可考虑同时加大MinSpareServers和MaxSpareServers。
MaxRequestsPerChild设置的是每个子进程可处理的请求数。每个子进程在处理了“MaxRequestsPerChild”个请求后将自动销毁。0意味着无限,最子进程永不销毁。虽然缺省设为0可以使每个子进程处理更多的请求,但如果设置成非零值也有两点重要的好处:1)可以防止意外的内存泄露;2)在服务器负载下载时会自动减少子进程数。
worker,使用多个子进程,同时每个子进程又有多个线程,每个线程在某个确定的时间只能维持一个连接,内存占用比较少,适合高流量的http服务器。缺点是假如一个线程崩溃,整个进程就会连同其相关联所有线程一起“死掉”,由于线程共享内存空间,所以要保证一个程式在运行时必须被系统识别为“每个线程都是安全的”。
worker的工作原理是,由主控制进程生成“StartServers”个子进程,每个子进程中包含固定的ThreadsPerChild线程数,各个线程独立地处理请求。同样,为了不在请求到来时再生成线程,MinSpareThreads和MaxSpareThreads设置了最少和最多的空闲线程数;而MaxClients设置了所有子进程中的线程总数。如果现有子进程中的线程总数不能满足负载,控制进程将派生新的子进程。
总的来说,prefork方式速度要稍高于worker,然而它需要的cpu和memory资源也稍多于woker。
查看apache的工作模式方式:
1)httpd -l 或 apachectl -l
# apachectl -l
Compiled in modules:
core.c
prefork.c
http_core.c
mod_so.c
可以看到prefork.c 说明现在在用prefork模式。
2)httpd -V 或 apachectl -V
# apachectl -V
Server version: Apache/2.2.15 (Unix)
Server built: Dec 8 2011 18:07:26
Server's Module Magic Number: 20051115:24
Server loaded: APR 1.3.9, APR-Util 1.3.9
Compiled using: APR 1.3.9, APR-Util 1.3.9
Architecture: 32-bit
Server MPM: Prefork
threaded: no
forked: yes (variable process count)
可以看到Server MPM: Prefork, 说明现在在用prefork模式
关于两种模式的区别,根据官方文档:
The workerMPM uses multiple child processes with many threads each. Each thread handles one connection at a time. Worker generally is a good choice for high-traffic servers because it has a smaller memory footprint than the prefork MPM.
The preforkMPM uses multiple child processes with one thread each. Each process handles one connection at a time. On many systems, prefork is comparable in speed to worker, but it uses more memory. Prefork’s threadless design has advantages over worker in some situations: it can be used with non-thread-safe third-party modules, and it is easier to debug on platforms with poor thread debugging support.
进程与线程区别与联系
划分尺度:线程更小,所以多线程程序并发性更高;
资源分配:进程是资源分配的基本单位,同一进程内多个线程共享其资源;
地址空间:进程拥有独立的地址空间,同一进程内多个线程共享其资源;
处理器调度:线程是处理器调度的基本单位;
执行:每个线程都有一个程序运行的入口,顺序执行序列和程序的出口,但线程不能单独执行,必须组成进程,一个进程至少有一个主线程。简而言之,一个程序至少有一个进程,一个进程至少有一个线程.
# prefork MPM
# StartServers: number of server processes to start
# MinSpareServers: minimum number of server processes which are kept spare
# MaxSpareServers: maximum number of server processes which are kept spare
# ServerLimit: maximum value for MaxClients for the lifetime of the server
# MaxClients: maximum number of server processes allowed to start
# MaxRequestsPerChild: maximum number of requests a server process serves
StartServers 8
#指定服务器启动时建立的子进程数量,ps -aux|grep httpd命令查看到进程就是这里的8个。
MinSpareServers 5
#指定空闲子进程的最小数量,假如当前空闲子进程数少于MinSpareServers ,那么Apache将创建一个进程,等待一秒钟,继续创建两个,再等待一秒钟,继续创建四个......如此按指数级增加创建进程数,最大达到每秒32个,直到满足MinSpareServers设置为止。此参数不宜设的太大。
MaxSpareServers 20
#配置空闲子进程的最大数量,假如当前有超过MaxSpareServers数量的空闲子进程,那么父进程将杀死多余的子进程。此参数不宜设的太大。假如您将该指令的值配置为比MinSpareServers小,Apache将会自动将其修改成"MinSpareServers+1"。
ServerLimit 20000
#上面有这个参数的英文释义。默认的MaxClient最大是256个线程,假如想配置更大的值,就的加上ServerLimit这个参数。20000是ServerLimit这个参数的最大值。假如需要更大,则必须编译apache,此前都是无需重新编译Apache。生效前提:必须放在其他指令的前面
MaxClients 256
#限定同一时间客户端最大接入请求的数量(单个进程并发线程数),任何超过MaxClients限制的请求都将进入等候队列,一旦一个链接被释放,队列中的请求将得到服务。要增大这个值,您必须同时增大ServerLimit。
MaxRequestsPerChild 4000
#每个子进程在其生存期内允许伺服的最大请求数量,到达MaxRequestsPerChild的限制后,子进程将会结束。 假如MaxRequestsPerChild为"0",子进程将永远不会结束。将MaxRequestsPerChild配置成非零值有两个好处:1.能 够防止(偶然的)内存泄漏无限进行,从而耗尽内存。 2.给进程一个有限寿命,从而有助于当服务器负载减轻的时候减少活动进程的数量。
perchild:
如果httpd -l列出perchild.c,则需要对下面的段进行配置:
NumServers 5 #服务器启动时启动的子进程数
StartThreads 5 #每个子进程启动时启动的线程数
MinSpareThreads 5 #内存中的最小空闲线程数
MaxSpareThreads 10 #最大空闲线程数
MaxThreadsPerChild 2000 #每个线程最多被请求多少次后退出。0不受限制
MaxRequestsPerChild 10000 #每个子进程服务多少次后被重新fork。0表示不受限制。
该模式下,子进程的数量是固定的,线程数不受限制。当客户端连接到服务器时,又空闲的线程提供服务。 如果空闲线程数不够,子进程自动产生线程来为新的连接服务。该模式用于多站点服务器。
一个典型的prefork配置和解释如下:
StartServers 20 # 启动服务数,对应启动进程数
MinSpareServers 50 # 最小空闲服务(提高响应能力),当前进程数 > 最小空闲服务 + 工作进程
MaxSpareServers 100 # 最大空闲服务(合理释放资源),当前进程数 < 最大空闲服务 + 工作进程
MaxClients 200 # 最大客户端,对应最大进程数
MaxRequestsPerChild 20000 # 每个服务最多处理的请求数量,设定一个有限值可以避免内存泄漏,但会消耗进程创建和销毁的资源
prefork是用起来最方便的设置,apache的默认设置也是如此。但该模式最内存资源消耗巨大。举例来说:
一般情况下,一个PHP网站中,每个server需要30M左右内存。按照前文的配置,最多将占用6G左右的内存。
如果资源不足,就会引发频繁的page fault,大量的SWAP,系统产生大量IO,导致宕机。
worker配置解释
ServerLimit 50
#服务器允许配置的进程数上限。这个指令和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",子进程将永远不会结束。对于KeepAlive链接,只有第一个请求会被计数。事实上,他改变了每个子进程限制最大链接数量的行为。
StartServers 15 # 启动的服务,对应进程
ServerLimit 15 # 最大服务限制 应满足 ServerLimit > MaxClients / ThreadsPerChild
MaxClients 256 # 最大客户端数量
ThreadLimit 256 # 最大线程数量
MinSpareThreads 30 # 最小空闲线程(提高响应能力),当前线程数 > 最小空闲服务 + 工作线程
MaxSpareThreads 305 # 最大空闲线程(合理释放资源),当前线程数 < 最大空闲服务 + 工作线程
ThreadsPerChild 255 # 每个子进程对应对线程数
MaxRequestsPerChild 0 # 每个进程处理的最大请求数量,达到即销毁新建进程worker模式是介于纯进程的prefork和纯线程的event模式直接的方式,在稳定性和资源上有一个取舍。
类似的,我们也主要关注其并发响应能力和资源占用情况。
上面的配置可以支持256的并发,内存占用约大于 15 * 30M = 450M 左右,算上线程的开销,大致小于500M。
其他建议并发和性能与很多东西相关,不是简单计算能够解决的。
这里的配置主要是避免系统瓶颈,同时保护服务器不要超过应用能力。
实际情况中,和磁盘性能,网络,CPU等都有关系,建议在对硬件的充分理解上,结合性能测试工具不断调优SYN_RECV表示正在等待处理的请求数;ESTABLISHED表示正常数据传输状态;TIME_WAIT表示处理完毕,等待超时结束的请求数。