首先,MPM是Multi-Processing Modules,表示Apache中的多路处理模块,目前在Linux上的Apache 2.2/2.4中包括三种模式:prefork、worker和event模式。
在使用Apache时,如何才能知道是在使用哪种MPM模式呢?
其实,apache或httpd的命令参数“-l”即可列出当前apache中已经编译了的模块,由于MPM只能在编译时指定其中一种,所以列出的静态模块中MPM只有1个,如下所示:
Python
[root@rhel6u4 ~]# httpd -l
Compiled in modules:
core.c
prefork.c #说明使用的是prefork模式
http_core.c
mod_so.c
master@ubuntu1204:~$ sudo apache2ctl -l
Compiled in modules:
core.c
mod_log_config.c
mod_logio.c
prefork.c #也是使用的prefork模式
http_core.c
mod_so.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@rhel6u4~]# httpd -l
Compiledinmodules:
core.c
prefork.c#说明使用的是prefork模式
http_core.c
mod_so.c
master@ubuntu1204:~$sudoapache2ctl-l
Compiledinmodules:
core.c
mod_log_config.c
mod_logio.c
prefork.c#也是使用的prefork模式
http_core.c
mod_so.c
另外,“ httpd -t -D DUMP_MODULES ”命令可以查看httpd加载的所有模块(包括静态编译的和动态共享的模块)。
在一些发行版的Apache安装时,可能不仅安装了prefork模式的httpd,也可能安装有worker/event模式的httpd供用户根据实际需要来选择。比如RHEL6.4中的httpd安装包就是同事提供了worker和event模式的httpd程序,如下所示:
Python
[root@rhel6u4~]# /usr/sbin/httpd.worker -l
Compiled in modules:
core.c
worker.c
http_core.c
mod_so.c
[root@rhel6u4 ~]# /usr/sbin/httpd.event -l
Compiled in modules:
core.c
event.c
http_core.c
mod_so.c
1
2
3
4
5
6
7
8
9
10
11
12
[root@rhel6u4~]# /usr/sbin/httpd.worker -l
Compiledinmodules:
core.c
worker.c
http_core.c
mod_so.c
[root@rhel6u4~]# /usr/sbin/httpd.event -l
Compiledinmodules:
core.c
event.c
http_core.c
mod_so.c
在RHEL系统中,可以很容易地配置httpd服务对prefork、worker和event等3种模式来进行选择。
编辑 /etc/sysconfig/httpd 文件,可以将 “HTTPD=/usr/sbin/httpd.worker”这行取消注释,然后重启httpd服务,即可使用到woker模式的httpd了;不过可能使用worker模式的httpd会与PHP的一些东西存在兼容性而导致httpd服务不能启动,如下所示,是需要安装 php-zts 软件包。
Python
[root@rhel6u4 ~]# service httpd start
Starting httpd: httpd.worker: Syntax error on line 221 of /etc/httpd/conf/httpd.conf: Syntax error on line 9 of /etc/httpd/conf.d/php.conf: Cannot load /etc/httpd/modules/libphp5-zts.so into server: /etc/httpd/modules/libphp5-zts.so: cannot open shared object file: No such file or directory
[FAILED]
[root@rhel6u4 ~]# yum install php-zts
[root@rhel6u4 ~]# service httpd start
Starting httpd: httpd.worker: Could not reliably determine the server's fully qualified domain name, using 192.168.199.112 for ServerName
[ OK ]
1
2
3
4
5
6
7
[root@rhel6u4~]# service httpd start
Startinghttpd:httpd.worker:Syntaxerroronline221of/etc/httpd/conf/httpd.conf:Syntaxerroronline9of/etc/httpd/conf.d/php.conf:Cannotload/etc/httpd/modules/libphp5-zts.sointoserver:/etc/httpd/modules/libphp5-zts.so:cannotopensharedobjectfile:Nosuchfileordirectory
[FAILED]
[root@rhel6u4~]# yum install php-zts
[root@rhel6u4~]# service httpd start
Startinghttpd:httpd.worker:Couldnotreliablydeterminetheserver'sfullyqualifieddomainname,using192.168.199.112forServerName
[OK]
在Apache编译时,做configure这一步,可以加上"--with-mpm=event"来将event编译作为MPM编译进去,同样也可以选择prefork和worker。另外,也可以将多个MPM编译为共享模块,configure中的参数为:--enable-mpms-shared=MPM-LIST (如:--enable-mpms-shared='prefork worker', --enable-mpms-shared=all)。
prefork, worker, event 三种模式的区别:
1. prefork 中没有线程的概念,是多进程模型,一个进程处理一个连接;稳定;响应快。其缺点是在连接数比较大时就非常消耗内存。
2. worker 是多进程多线程模型,一个进程有多个线程,每个线程处理一个连接。与prefork相比,worker模式更节省系统的内存资源。不过,需要注意worker模式下的Apache与php等程序模块的兼容性。
3. event 是worker模式的变种,它把服务进程从连接中分离出来,在开启KeepAlive的场合下相对worker模式能够承受更高的并发负载。event模式不能很好的支持https的访问(HTTP认证相关的问题)。
Prefork MPM uses multiple child processes with one thread each and each process handles one connection at a time.
Worker MPM uses multiple child processes with many threads each. Each thread handles one connection at a time.
最后,BTW,之前一直都只用的Apache,先Nginx 越来越流行了,找个机会也了解一下。
参考资料:
1. 谈了3种MPM的使用:http://www.vps.net/blog/2013/04/08/apache-mpms-prefork-worker-and-event/
2. Apache官方文档:http://httpd.apache.org/docs/2.4/mpm.html