其实Apache
本身的并发能力是比较强大的,但是Debian/Ubuntu
默认安装的是Prefork
模式下的Apache
。所以导致很多人后面盲目的去使用lighttpd
或nginx
一类替代软件。但是这类软件有一定的兼容问题,部分情况下可能工作的并不好。那么, 是不是Apache
并发就不行了呢?答案当然是否定的。
在进行配置之前,我们首先要知道什么是Prefork
模式,什么是Worker
模式,什么是Event
模式,以及什么是MPM
。
MPM
(Multi-Processing Modules
,表示Apache
中的多路处理模块)是Apache2
引入的一个概念,就是将结构模块化。把核心任务处理作为一个可插拔的模块,即MPM
,使其能针对不同的环境进行优化。在这个情况下,就诞生出了处理模式的概念。处理模式现在分为Prefork
、Worker
、Event
三种。
Prefork MPM
基于非线程模型,和Apache 1.x
版本中的处理方式很相似。Prefork MPM
在所有情况下都很安全,对运行非线程安全(non-thread-safe)模式的软件如PHP
,它是唯一的安全选择。对于某些应用程序,包括在Apache 1.3
上非常流行的程序(如简单静态页面、CGI
脚本等),Prefork MPM
是最好的选择。另一方面,prefork
用单独的子进程来处理不同的请求,进程之间是彼此独立的,这也使其成为最稳定的MPM
之一。但是由于每一个请求都会产生一个新的进程,导致系统资源(尤其是内存)消耗的很快,一旦并发量较大的时候,大量的Apache
进程会占用巨大的内存空间。
而Worker MPM
基于线程模式,具有内存消耗低(对繁忙的服务很重要)、扩展性在某些特定应用情况下比Prefork
更好等优点。在这个模式下,采用的进程和线程混合的形式处理请求。由于使用线程来处理,所以可以处理相对海量的请求,而系统资源的开销要小于基于进程的Prefork
模式。
以上两种稳定的MPM
方式在非常繁忙的服务器应用下都有些不足。尽管HTTP
的Keepalive
方式能减少TCP
连接数量和网络负载,但是Keepalive
需要和服务进程或者线程绑定,这就导致一个繁忙的服务器会耗光所有的线程。Event MPM
是解决这个问题的一种新模型,它把服务进程从连接中分离出来。在服务器处理速度很快,同时具有非常高的点击率时,可用的线程数量就是关键的资源限制,此时Event MPM
方式是最有效的。一个以Worker MPM
方式工作的繁忙服务器能够承受每秒好几万次的访问量(例如在大型新闻服务站点的高峰时),而Event MPM
可以用来处理更高负载。值得注意的是,Event MPM
在Apache 2.4 之前的版本中不能在安全HTTP
(HTTPS
)访问下工作,Ubuntu 12.04
中默认安装的版本是Apache 2.2
因此还不能完全使用。
一目了然,三种MPM
模式各有各的优缺点。但是如果我们经常遇到访问量一大,服务器资源就吃紧的情况,那么就是Prefork
模式瓶颈了。在其他两类MPM
中,通用的做法还是使用Worker
模式来解决问题。Event MPM
由于不支持安全连接(HTTPS
)所以导致应用有一定的局限性。
下面我们就以Debian/Ubuntu
下将Apache
的模式从Prefork
设置为Worker
为例,来说明一下操作步骤。前面也提到了,由于Worker
模式与PHP
的执行方式不同,所以如果简单的输入
1 |
$sudo apt-get install apache2-mpm-worker |
会导致PHP
无法使用。当然了,如果你的网页只有静态页面,不需要使用PHP
,那么使用上面这条指令就会搞定一切。这里我们着重讨论下要使用PHP的情况下,应该如何配置Apache
的Worker
模式。
先查看Apache
当前的加载的模块
1 |
apache2 -l |
查看到输出为
1 2 3 4 5 6 7 |
Compiled in modules: core.c mod_log_config.c mod_logio.c prefork.c http_core.c mod_so.c |
可以看到其中的
1 |
prefork.c #说明使用的是prefork模式 |
1. 安装Apache的fcgid模块,使用它来启用PHP。
1 |
sudo apt-get install libapache2-mod-fcgid |
2. 设置fcgid模块的配置文件,使其能够调用PHP。
1 |
sudo vim /etc/apache2/mods-available/fcgid.conf |
可以看到内容为如下
1 2 3 4 |
<IfModule mod_fcgid.c> AddHandler fcgid-script .fcgi FcgidConnectTimeout 20 </IfModule> |
在 AddHandler 后面增加 PHP支持,修改为
1 2 3 4 5 |
<IfModule mod_fcgid.c> AddHandler fcgid-script .fcgi .php FcgidConnectTimeout 20 DefaultMaxClassProcessCount 10 </IfModule> |
注意 DefaultMaxClassProcessCount 10 用来限制php5-cgi 最大的进程并发数,这个可以避免创建了太多的php5-cgi进程,耗尽系统内存,导致OOM Killer 杀死服务的问题,后面的数字根据自己机器的配置情况自行调整即可。
3. 安装php5-cgi
1 |
sudo apt-get install php5-cgi |
4. 设置Apache的配置文件,使其能够调用fcgid模块来启动PHP。
1 |
sudo vim /etc/apache2/sites-available/default |
原内容为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
<VirtualHost *:80> ServerAdmin webmaster@localhost DocumentRoot /var/www <Directory /> Options FollowSymLinks AllowOverride None </Directory> <Directory /var/www/> Options Indexes FollowSymLinks MultiViews AllowOverride None Order allow,deny allow from all </Directory> ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/ <Directory "/usr/lib/cgi-bin"> AllowOverride None Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch Order allow,deny Allow from all </Directory> ErrorLog ${APACHE_LOG_DIR}/error.log # Possible values include: debug, info, notice, warn, error, crit, # alert, emerg. LogLevel warn CustomLog ${APACHE_LOG_DIR}/access.log combined Alias /doc/ "/usr/share/doc/" <Directory "/usr/share/doc/"> Options Indexes MultiViews FollowSymLinks AllowOverride None Order deny,allow Deny from all Allow from 127.0.0.0/255.0.0.0 ::1/128 </Directory> </VirtualHost> |
修改为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
<VirtualHost *:80> ServerAdmin webmaster@localhost DocumentRoot /var/www <Directory /> Options FollowSymLinks AllowOverride None </Directory> <Directory /var/www/> Options Indexes FollowSymLinks MultiViews AllowOverride None FCGIWrapper /usr/bin/php5-cgi .php Options ExecCGI SymLinksIfOwnerMatch Order allow,deny allow from all </Directory> ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/ <Directory "/usr/lib/cgi-bin"> AllowOverride None Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch Order allow,deny Allow from all </Directory> ErrorLog ${APACHE_LOG_DIR}/error.log # Possible values include: debug, info, notice, warn, error, crit, # alert, emerg. LogLevel warn CustomLog ${APACHE_LOG_DIR}/access.log combined Alias /doc/ "/usr/share/doc/" <Directory "/usr/share/doc/"> Options Indexes MultiViews FollowSymLinks AllowOverride None Order deny,allow Deny from all Allow from 127.0.0.0/255.0.0.0 ::1/128 </Directory> </VirtualHost> |
即在<Directory /var/www/></Directory>之间增加
1 2 |
FCGIWrapper /usr/bin/php5-cgi .php Options ExecCGI SymLinksIfOwnerMatch |
5. 安装Apache的Worker MPM模块。
1 |
sudo apt-get install apache2-mpm-worker |
需要注意的是,如果之前有安装了php5-gd和php5-mysql模块,Ubuntu在配置Apache的Worker模式的时候可能会将其卸载,可以重新安装一次以防万一:
1 |
sudo apt-get install php5-gd php5-mysql |
完成之后继续执行
1 |
apache2 -l |
查看到输出为
1 2 3 4 5 6 7 |
Compiled in modules: core.c mod_log_config.c mod_logio.c worker.c http_core.c mod_so.c |
可以看到其中的
1 |
worker.c #说明使用的是work模式 |