apache有几种工作模式?怎么查看和修改apache的工作模式?
apache的工作模式有:beos,event,worker,prefork,mpmt_os2。
在linux(centos)下使用#http –l 命令可以查看当前使用的工作模式。也可以使用#apachectl -l命令。看到的prefork.c,说明使用的prefork工作模式。可以在编译的时候使用#–with-mpm=prefork对应的工作模式名称来修改工作模式。beos工作模式(跟linux关系不大,或者暂时用不上)
在Beos系统上的工作模式,使用一个单独的控制线程来创建和控制处理请求的工作线程。event模式由于把服务进程从链接中分离出来,在开启KeepAlive场合下相对worker模式能够承受的了更高的负载。event模式为 worker开发的变种模式,配置以及指令与worker完全相同。不过event模式不能很好的支持https的访问,有时还会出现一系列的问题。
worker工作模式(与php配合不好,或者说暂时用不上)
worker模式由于使用线程来进行处理请求,所以能够处理海量请求,而系统资源的开销要小于基于进程的服务器。同时worker模式也使用了多进程,每个进程又有着多个线程,以获得基于进程服务器的稳定性。
mpmt_os2工作模式(很少用,或者说暂时用不上)
mpmt_os2是专门针对OS/2优化过的混合多进程多线程多路处理模块(MPM) 。
prefork工作模式(本篇文章的主角,使用最多而且最稳定的工作模式)
prefork工作模式是linux下apache安装时候的默认工作模式,是使用最普遍的工作模式。为了能够简单的明白他的工作原理,下面是一个假设:
有一台正在运行的apache服务器,用户A访问该apache的时候apache建立一个新的进程1处理用户A的请求。
这时又有一个用户B访问该apache,apache又建立一个新的进程2处理用户B的请求。
后来又有用户C,D,E访问该apache,apache又建立三个进程3,4,5处理他们的请求。
如果每当一个新用户访问该apache,apache再建立一个新的进程处理用户的请求,是不是太慢了呢?
所以apache的prefork模式在apache第一次启动的时候就建立5个进程,等待用户的连接请求,有一个用户访问,就有一个进程处理他的请求。那么如果有5个用户同时访问apache,apache第一次建立的5个进程全部用光了,所以apache就再从新在建立5个进程,等待下一批用户的请求。
prefork模式会根据服务器的硬件情况,设定apache最多只能同时建立256个进程。再多的请求就只能等待前面的进程处理完毕在进行处理。
假设完毕!
上面的假设就是prefork模式的工作原理。但是上面假设中具体的数字不是定死的,而是通过prefork模式的配置来设置的。下面是http.conf中的配置信息。
StartServers apache启动时候默认开始的进程数
MinSpareServers 最小的闲置进程数 apache在没有用户访问时候有5个闲置的进程,如果有一个用户访问网站。则闲置的进程就只有4个,这个值小于MinSpareServers,所以 apache就以第一秒1个进程,第二秒2个进程,第三秒4个进程的速度新建空闲进程。直到大于等于MinSpareServers个空闲进程才结束。
MaxSpareServers 最大的闲置进程数 ServerLimit 最大的进程总数 MaxClients 最大的进程总数 apache在没有用户访问时候有5个闲置的进程,如果有5个用户同时访问网站。则闲置的进程就只有0个,这个值小于 MinSpareServers,所以apache就以第一秒1个进程,第二秒2个进程,第三秒4个进程的速度新建空闲进程。直到大于等于 MinSpareServers个空闲进程才结束。在这个例子中直到第三秒,一共生成1+2+4个进程才能满足大于等于MinSpareServers的 要求。后来这5个用户访问完apache,访问结束,关闭浏览器。所以apache就有了5+7个空闲的进程。这时空闲的进程比较多,apache就开始 关闭一些进程,直到满足小于MaxSpareServers个空闲进程才结束。如果该值小于MinSpareServers则apache默认将该值设置 成MinSpareServers+1。
ServerLimit 这个参数是控制apache的进程总数的,那为什么会有两个参数控制apache的进程总数呢?这个参数在apache1的时代是没有的,因为那个时候有 个256M内存的服务器就很厉害了。后来apache2的时代到来,服务器的硬件也得到升级。很多服务器都是4G内存,还有很多比4G内存大的服务器出 现。apache1的时代只有一个MaxClients参数控制进程总数就够了,而这个参数最大值是256定死了。但是到了apache2的时代必须调整 ServerLimit值大于256才能使MaxClient支持大于256的值。
MaxClients apache最大的进程数。apache1的时代只有一个MaxClients参数控制进程总数就够了,而这个参数最大值是256定死了。但是到了apache2的时代必须调整ServerLimit值大于256才能使MaxClient支持大于256的值。
MaxRequestsPerChild 每个进程处理的最多请求数 apache在没有用户访问的时候有5个空闲进程。当一个用户访问网站,访问完又离开。则apache的第一个进程就处理了一个请求,从新进入闲置状态。 再有一个用户访问网站,访问完后离开。则apache的第一个进程就处理了1+1个请求。这样继续访问3998个用户,这个进程就处理了4000个请求, 之后就自动关闭这个进程。这个时候apache就只有4个限制的进程,小于MinSpareServers值所以apache从今建立一个空闲进程。至于 为什么处理完4000个请求就要关闭这个进程呢?答案之一:为了防止内存的泄露。
首先查看apache第一次启动时候的空闲进程:
linux(centos)下查看apache的进程可以使用#ps -ef|grep httpd命令,查看apache进程的内存使用情况可以使用#ps –U apache –u apache u命令
#service httpd restrat:重启apache,初始化进程
#ps -ef|grep httpd:用户名为apache的才是apache用于处理用户请求的进程
#ps –U apache –u apache u:查看用户名为apache的进程(即apache为了处理用户请求而建立的进程详情)
1,apache是严格按照prefork模式的配置参数来进程分配和管理的。不像网上有些文章那样修改了某个值,apache不起作用。只能说您改的不对,或者说您对上面的内容还不够理解。
2,MaxClients值就是apache的最大进程数。不像网上有些文章说的这个值越大越好(有的文章既然推荐该值为4000),您可以从上面的进程 图中看到apache的每个进程的%MEM(内存占用百分比)值为0.5%左右。所以这个值的具体设置的最大数位:100/0.5 = 200。而这也只是在这个服务器只有一个apache的情况下。如果服务器有其他程序需要占用内存(比如mysql)这个值要小于200。你总不能把操作 系统的所有内存都给apache吧?
3,每个浏览器是一个用户,每个用户就是一条进程。明白意思了吧?我的这台服务器的并发量只有200。就是说我的这台服务器只能支持同时200个用户访 问,再多的用户访问就只能是等待。或者说我这台服务器只支持200个浏览器的访问。关于服务器的并发我会在下面一片文章中详细讲解。
4,200的并发量很小吗?要知道apache处理数据的速度是相当快的。一条正常的首页访问可能就一秒钟处理完毕。所以在假想的状态下,我的这台 服务器,每分钟可以访问60*200=12000个用户。每天可以访问12000*60*24=17280000个用户的访问。这当然是在完全饱和的访问 状态的假想数据。下一篇文章我会详细讲解网站并发,请求,连击等内容。
5,如果访问的用户数大于MaxClients的数,多出的用户不会立刻断掉连接,还是会建立TCP连接。只不过会等待前面的用户处理完在得到相应。在php.ini,http.conf,操作系统设定的超时时间内得不到相应才会断掉连接。
不是所有请求都会建立连接,限制是linux操作系统上,或者说apache所在的操作系统。既然浏览器可以发起无数个请求,那么能不能成功建立连接就是服务端的事情。那么到底是apache限制了最大的连接数还是linux限制了最大的连接数?还是PHP限制了最大连接数?或者说是mysql限制了最大连接数?答案是linux限制了浏览器和apache之间的最大连接数。下面就通具体的测试来回答。
首先我们假设是apache限制了最大连接数。打开apache的httpd.conf文件。找了半天发现只有下这一段跟最大连接数有点关系。
对于上图的参数不明白可以查看上一篇文章从工作模式讲解apache进程和用户请求的关系。
按照如上图一样设置后进行测试。
参数:
StartServers
1
MinSpareServers
1
MaxSpareServers
2
ServerLimit
256
MaxClients
3
MaxRequestPerChild
4000
测试环境:
服务器
虚拟机上的centOS4.5
客户端
本机上的IE浏览器
服务器地址
192.168.212.128
客户端地址
192.168.212.1
访问文件
<?php
for($i = 0;$i <= 10;$i++){
echo date('H:i:s',time());
echo '<br/>';
sleep(10);
}
?>
通过10个IE浏览器模拟10个用户同时对apache发起请求:(基本同时访问)
通过netstat命令可以看到这10个请求都建立了连接。
#netstat -nt|grep –i ’80′
再看看apache的情况:
#ps –U apache u
看到了吧?第一次同时访问时候apache只启用了3个进程处理前三个用户的请求。
过10*10秒之后再看看连服务器的连接状态和apache进程状态。
可以看到第一批3个用户的请求处理完毕,3个连接状态为TIME_WAIT。可以从前面的IE浏览器打印的内容看到最后的响应时间为18:20:35。要知道这个时候另外7个页面还是在载入中。可以看到这7个浏览器的进度条在走,而不是没有响应,也没有提示403等错误。
看到apache的进程还是只有3个,因为上面的MaxClients=3限制了最大的进程数为3。而不会开启多余的进程处理请求。
再看看过了2*10*10秒后的状态。
可以看到第一批3个用户的连接已经断开,第二批3个用户的请求已经处理完毕,正在准备断开连接,TIME_WAIT会在2*SML秒后进入 CLOSED状态。即断开连接。可以从前面IE浏览器打印的内容看到开始响应时间为18:20:52。最后响应时间为18:22:32。第一批和第二批浏 览器已经显示完毕,剩下的4个浏览器状态是正在载入中,可以看到进度条在走动。
看到apache的进程还是只有3个。
再看看过了3*10*10秒后的状态。
可以看到这时前面的6个连接都已经断开,第三批浏览器的请求已经处理完毕正在准备断开连接,TIME_WAIT会在2*SML秒后进入CLOSED 状态。即断开连接。可以从前面IE浏览器打印的内容看到开始响应时间为18:22:42。最后响应时间为18:24:22。第一批,第二批,第三批浏览器 已经显示完毕,剩下的1个浏览器状态是正在载入中,可以看到进度条在走动。
看到apache的进程还是只有3个。
再看看过了4*10*10秒后的状态。
可以看到这时前面的9个连接都已经断开,第四批浏览器的请求已经处理完毕正在准备断开连接,TIME_WAIT会在2*SML秒后进入CLOSED 状态。即断开连接。可以从前面IE浏览器打印的内容看到开始响应时间为18:24:25。最后响应时间为18:26:05。第一批,第二批,第三批,第四 批浏览器全部显示完毕。
可以看到apache的进程已经减少为2个。
测试得到的结论
上面的测试可以看到,浏览器与apache之间的最大TCP连接数不是有apache限制的。apache工作模式中MaxClients等参数只 是限制了apache的进程数量,并没有限制浏览器和apache的连接数量。就算apache的进程已经到达MaxClients的最大数,其他浏览器 还是可以访问。而且访问也不会拒绝,只是在等待apache的进程将前面的请求处理完,再处理这些没有响应的请求。
为什么apache不能限制最大的TCP连接数呢?答案:TCP连接是在链路层,apache是基于http协议的在应用层。
下面看看linux是怎么限制TCP连接的最大数的。
首先使用sysctl -a命令看看linux下面的系统配置参数。
#sysctl –a
往下翻翻可以看到
还有
看到这么多系统配置参数,是不是有个参数可以控制TCP的最大连接数呢?
找了很久,没有发现可以直接控制TCP最大连接数的参数,每个连接成立以后linux都会对其进行维护(并且创建维护文件,linux的防火墙就是 根据这个文件的)。发现有个参数ip_conntrack_max就是这个维护文件最大数。(可以使用modprobe ip_conntrack开始这个参数。可以使用#less /proc/net/ip_conntrack |wc –l 查看当前已经建立的该文件数,连接断开后这个文件也会关闭)
#sysctl -a|grep ip_conntrack_max
虽然看到两个,但是这两个文件是同步的,修改后会自动同步。
我们把它的值修改为1,虽然有点极端,但是可以很好解释为很么是linux限制了浏览器的最大TCP连接数。
#echo 1 > ip_conntrack_max
使用两个IE浏览模拟2个用户同时访问apache。使用netstat命令查看。
#netstat -nt|grep –i ’80′
看到问题了吧。只有一个连接,第二个访问的浏览根本就没有反应。
测试得到的结论
在我们把ip_conntrack_max设置为1的时候,浏览器不敢发送多少请求,linux只会和它建立一个连接。
那么linux没有专门的值来控制TCP连接的最大数呢?有,只不是linux把个限制的条件细化了。比如:同时可以建立多少CLOSE_WAIT 状态的连接数,同时可以建立多少个TIME_WAIT状态的连接数,等等等。所以想要控制apache的最大连接数,需要通过配合这些数据进行组合。
总结
如果认真读完上面的内容,会的到下面的结论。
1,用户的浏览器可以对apache发起N个请求。N的数值可能会很大。
2,只有M(M小于N)个请求会跟apache建立连接(只是建立连接,并不是处理)。而这个M的值是由linux服务器控制。linux会根据硬件的情况会给出默认值。我们可以通过各个参数的组合来计算最后的TCP连接数的最大限制。
3,只有P(P小于M)个连接会得到apache的处理。apache会建立P个进程处理这P个连接。这个P的值是apache的ClientMax等参数控制的。