Apache的工作模式原理

1、 多模式处理模块概述
Apache 的核心模块叫多路处理模块(Multi-Processing Module,简称 MPM)。
Apache 作为现今 Web 服务器用的最广泛也是最稳定的开源服务器软件,其工作模式有
许多种 (mpm_beos、 mpm_event、 mpm_netware、 mpmt_os2、 mpm_prefork、 mpm_winnt、
mpm_worker),源码包安装 httpd 时可查看 httpd-mpm.conf 文件,该文件位于 conf/extra目录中。

mpm_event 模块可以看作是 mpm_worker 模块的一个变种
Linux 平台下主要有两种模式: prefork 模式和 worker 模式。
2prefork 工作模式
1prefork 工作模式概述
prefork 是一种多路处理模块(MPM),实现了一个进程型的、预派生的 Web 服务器,适

合于没有线程安全库、需要避免线程兼容性问题的系统。
prefork 的工作原理是,控制进程在最初建立“StartServers”个子进程后,为了满足
MinSpareServers 设置的需要创建一个进程,等待一秒钟,继续创建两个,再等待一秒钟,
继续创建四个……如此按指数级增加创建的进程数, 最多达到每秒 32 个,直到满足
MinSpareServers 设置的值为止。这就是预派生(prefork)的由来。这种模式可以不必在请
求到来时再产生新的进程,从而减小了系统开销以增加性能。
在要求每个请求相互独立的情况下具有很好的特性,若一个请求出现问题不会影响到其
他请求。具有很强的自我调节能力,只需要很少的配置指令进行调整就可以适合于企业应用
要求。最重要的是将 MaxClients 设置为一个足够大的数值以处理潜在的请求高峰,同时又
不能太大,以避免所需要的内存超出物理内存的大小。
2、工作方式
一个单独的控制进程(父进程)负责产生子进程,子进程用于监听请求并作出应答,因
此在内存中会一直存在一些备用的(spare)或是空闲的子进程用于接收和响应新的请求,
可加快响应速度。
父进程通常以 root身份运行,以绑定 80端口,子进程通常以一个低特权的用户(daemon)
运行,可通过配置项的 User 和 Group 配置。运行子进程的用户必须要对网站内容有读取权
限,但是对其他资源必须拥有尽可能少的权限,以保证系统安全。
编译安装时没有指定工作模式,默认会使用 prefork 模式,可用 httpd -l 或 httpd-V
查看。
[root@crushlinux ~]# httpd -l | grep prefork
prefork.c
[root@crushlinux ~]# httpd -V
Server version: Apache/2.2.31 (Unix)
Server built: Apr 13 2016 13:40:06
Server's Module Magic Number: 20051115:40
Server loaded: APR 1.5.2, APR-Util 1.5.4
Compiled using: APR 1.5.2, APR-Util 1.5.4
Architecture: 64-bit
Server MPM: Prefork
threaded: no
forked: yes (variable process count)
Server compiled with....
-D APACHE_MPM_DIR="server/mpm/prefork"
在 httpd-mpm.conf 配置文件中,以下是 prefork 模块的定义
8 / 16
StartServers 服务器启动时建立的子进程数量
MinSpareServers 空闲子进程最小数量,当空闲子进程数少于该数值将产生新的子进程
MaxSpareServers 空闲子进程最大数量,当空闲子进程数大于该数值将杀死多于子进程。
这个值不要设得过大,但如果设的值比 MinSpareServers 小, Apache 会自动把其调整为
MinSpareServers+1。
注意: 如果站点负载较大,可考虑同时加大 MinSpareServers 和 MaxSpareServers。
MaxClients 限定最大用户并发数, 是对 Apache 性能影响最大的参数。 其缺省值 150
是远远不够的,如果请求总数已达到这个值(可通过 ps -ef|grep http|wc -l 来确认),
那么后面的请求就需要排队,直到某个进程处理请求完毕。这就是系统资源还剩下很多而
HTTP 访问却很慢的主要原因。系统管理员可以根据硬件配置和负载情况来动态调整这个
值。虽然理论上这个值越大,可以处理的请求就越多, 但 Apache 默认的限制不能大于
256。如果把这个值设为大于 256,那么 Apache 将无法起动。事实上, 256 对于负载稍重的
站点也是不够的。在 Apache 1.3 中,这是个硬限制。如果要加大这个值,必须在
“configure”前手工修改的源代码树下的 src/include/httpd.h 中查找 256,就会发现
“#define HARD_SERVER_LIMIT 256”这行。把 256 改为要增大的值(如 4000),然后重新
编译 Apache 即可。在 Apache 2.0 中新加入了 ServerLimit 指令,使得无须重编译 Apache
就可以加大 MaxClients。
MaxRequestsPerChild 每个子进程在其生存期内允许伺服的最大请求数量。如果设置为
“0”,子进程将永远不会结束。其中 MaxRequestsPerChild 建议设定为一个非零值,子进
程服务的请求数超过设置的值的限制后,子进程将会自动销毁。 如果设成非零值也有两点
重要的好处, 能够防止内存泄漏无限进行,从而避免内存耗尽, 也有助于当服务器负载减
轻的时候减少活动进程的数量。
3、配置 prefork 工作模式
优化时要根据企业网站情况进行调整
[root@crushlinux ~]# vim /usr/local/httpd/conf/httpd.conf
377 # Server-pool management (MPM specific)
378 Include conf/extra/httpd-mpm.conf
[root@crushlinux ~]# /etc/init.d/httpd stop
[root@crushlinux ~]# free -m
total used free shared buffers cached
9 / 16
Mem: 474 160 313 0 18 58
-/+ buffers/cache: 84 390
Swap: 3679 0 3679
内存(以 MB 为单位)除以 2,约等于 MaxClients 数值
[root@crushlinux ~]# cd /usr/local/httpd/conf/extra/
[root@crushlinux extra]# cp -p httpd-mpm.conf httpd-mpm.conf.origin
[root@crushlinux extra]# vim httpd-mpm.conf
36 <IfModule mpm_prefork_module>
37 ServerLimit 1000
38 StartServers 5
39 MinSpareServers 5
40 MaxSpareServers 10
41 MaxClients 250
42 MaxRequestsPerChild 10000
43 </IfModule>
上图为虚拟机 512MB 内存的参考配置
[root@crushlinux extra]# /etc/init.d/httpd restart
配置优化建议:
·StartServers 与 MinServers 应该一样
·根据网站的访问量进行设置,如设置 MaxClients 的数量为较大的一个值,以满足请

·MaxRequestsPerChild 应该设置一个值(经验值 10000~30000)
·要结合系统的内存数量及负载进行配置
·默认的 MaxClients 最大是 150 个进程,如配置更大值,就得配置 ServerLimit(服
务极限)这个参数, 200000 是该参数的最大值, 如果一定要再加大这个数值,对位于源代码
树下 server/mpm/prefork/prefork.c 中以下两行做相应修改即可:
#define DEFAULT_SERVER_LIMIT 256
#define MAX_SERVER_LIMIT 200000
ab 压力测试, 与调整前对比
Server Software: Apache/2.2.31
Server Hostname: localhost
Server Port: 80
Document Path: /index.html
Document Length: 63 bytes
Concurrency Level: 800
Time taken for tests: 2.069 seconds
10 / 16
Complete requests: 5000
Failed requests: 0
Write errors: 0
Total transferred: 1572512 bytes
HTML transferred: 315504 bytes
Requests per second: 2416.80 [#/sec] (mean)
Time per request: 331.016 [ms] (mean)
Time per request: 0.414 [ms] (mean, across all concurrent requests)
Transfer rate: 742.28 [Kbytes/sec] received
3、 worker 工作模式
1worker 工作模式概述
worker 也是多路处理模块(MPM),使服务器支持混合的多线程多进程。由于使用线程
来处理请求,所以可以处理海量请求,而系统资源的开销小于基于进程的 MPM。但是也使用
了多进程,每个进程又有多个线程,以获得基于进程的 MPM 的稳定性。
控制该 MPM 的最重要的指令是:控制每个子进程允许建立的线程数 ThreadsPerChild 指
令和控制允许建立的总线程数的 MaxClients 指令。
在./configure --with-mpm=worker 后,进行 make 编译、 make install 才可以支持
prefork 模式与 worker 模式的对比

Prefork worker
多进程 多进程多线程
较慢 较快
CPU 占用率高 CPU 占用率低
稳定 较不稳定
对 bug 自我排错 无法自我排错
小流量网站使用 大流量网站使用


2、工作方式
worker 的工作原理是,由主控制进程生成“StartServers”个子进程,每个子进程中
包含固定的 ThreadsPerChild 线程数,各个线程独立地处理请求。同样,为了不再请求到
来时再生成线程, MinSpareThreads 和 MaxSpareThreads 设置了最少和最多的空闲线程
数;而 MaxClients 设置了所有子进程中的线程总数。如果现有子进程中的线程总数不能满
足负载,控制进程将派生新的子进程。
MinSpareThreads 和 MaxSpareThreads 的最大缺省值分别是 75 和 250。这两个参数对
11 / 16
Apache 的性能影响并不大,可以按照实际情况相应调节。
ThreadsPerChild 是 worker MPM 中与性能相关最密切的指令。 ThreadsPerChild 的最
大缺省值是 64,如果负载较大, 64 也是不够的。这时要使用 ThreadLimit 指令, 它的最大
缺省值是 20000。上述两个值位于源码树 server/mpm/worker/worker.c 中的以下两行:
#define DEFAULT_THREAD_LIMIT 64
#define MAX_THREAD_LIMIT 20000
这两行对应着 ThreadsPerChild 和 ThreadLimit 的限制数。最好在 configure 之前就
把 64 改成所希望的值。注意,不要把这两个值设得太高,超过系统的处理能力,从而因
Apache 不起动使系统很不稳定。
Worker 模式下所能同时处理的请求总数是由子进程总数乘以 ThreadsPerChild 值决定
的,应该大于等于 MaxClients。如果负载很大,现有的子进程数不能满足时,控制进程会
派生新的子进程。 默认最大的子进程总数是 16,加大时也需要声明 ServerLimit(最大值
是 20000)。这两个值位于源码树 server/mpm/worker/worker.c 中的以下两行:
#define DEFAULT_SERVER_LIMIT 16
#define MAX_SERVER_LIMIT 20000
需要注意的是,如果声明了 ServerLimit,那么它乘以 ThreadsPerChild 的值必须大
于等于 MaxClients,而且 MaxClients 必须是 ThreadsPerChild 的整数倍,否则 Apache 将
会自动调节到一个相应值(可能是个非期望值)
每个进程能够拥有的线程数量是固定的,服务器会根据负载情况增加或减少进程数
量。一个单独的控制进程(父进程)负责子进程的建立。每个子进程能够建立
ThreadsPerChild 数量的服务线程和一个监听线程,监听线程监听接入请求并将其传递给
服务线程处理和应答。
Apache 总是会维持一个备用(spare)或是空闲的服务线程池,客户端无需等待新的
线程或进程的建立即可得到服务。
父进程一般都是以 root 身份启动,以绑定 80 端口;随后, Apache 以较低权限的用户
建立子进程和线程。 User 和 Group 指令用于配置 Apache 子进程的运行用户。子进程要对
网页内容拥有读权限,但应该尽可能限制权限。
在 httpd-mpm.conf 中 worker 的定义
StartServers 服务器启动时建立的子进程数量
MaxClients 限定最大用户并发数(数值为 ServerLimit 的值乘以 ThreadsPerChild
的值)
12 / 16
MinSpareThreads 空闲子线程最小数量,当空闲子线程数少于该数值将产生新的子线程
MaxSpareServers 空闲子线程最大数量,当空闲子线程数大于该数值将杀死多于子线程
MaxRequestsPerChild 每个子进程在其生存期内允许伺服的最大请求数量。如果设置为“0”,
子进程将永远不会结束。
优化时要根据企业网站情况进行调整
[root@crushlinux extra]# /etc/init.d/httpd restart
配置优化建议:
·根据网站的繁忙程度设置空闲进程数
·所有的线程数要大于 MaxClient 的设置值
·根据网站的实际运营情况适当调整
·考虑系统的内存与实际负载情况

猜你喜欢

转载自www.cnblogs.com/bingguoguo/p/9045527.html