1 强制类型转换为bool
!!expr
解析:!expr是将expr强制转换为bool,并取非,!!取得正常的值
2 Math.floor(f)
~~f
例如:Math.floor(840,89) = 840 ,~~840.89 = 840
本篇文章是为了详细理解apache服务器的优化而编写的基础文章。这里主要讲解他们之间的关系。如果您想理解apache的并发的概念可以查看上一篇文章从工作模式讲解apache进程和用户请求的关系。如果您想理解apache和浏览器连接相关内容您可以查看浏览器与apache通讯中的TCP连接状态迁移。
并发(并发数量):就是apache的并发数量,更直接就是apache为了处理用户请求开启的进程数量,简单理解就是apache的进程数量。
连接(TCP连接):apache和浏览器之间是通过TCP/IP协议进行通信的,这里的连接就是apache和浏览器之间的TCP连接。
请求(浏览器的请求):apache服务器一直监听80端口,不会发起主动请求。而浏览器会向apache发起连接请求。这里讲的请求就是浏览器的请求。
一个浏览器能发起几个请求?是什么限制浏览器发起请求?
答案:无数,如果用户的电脑配置允许。
这个应该是废话,浏览器在客户端,用户想发几个就发几个请求。限制条件应该是用户的电脑配置吧。一般一台电脑开几百个浏览器对同一个网站发请求应该是没有问题。
是不是每个浏览器的请求都能够建立连接?是什么限制了浏览器和apache的连接数?
答案:不是所有请求都会建立连接,限制是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等参数控制的。
补充
这篇文章是本人对apache和浏览器之间的请求,连接,并发的个人观念。难免会有错误。
什么是apache的工作模式?
个人理解:apache的工作模式就是apache在运行时候的内存分配,进程和线程的使用方式。举个例子:一台apache正在运行的服务器,如果有个用户访问这个apache,那么apache是启用一个进程来处理用户的请求呢?还是在已有的进程中启用一个线程来处理该用户的请求?这个选择就是 apache的工作模式来确定的。如果指定了某个工作模式比如prefork模式,那么每个用户的请求就要启用一个进程来处理。
apache有几种工作模式?怎么查看和修改apache的工作模式?
apache的工作模式有:beos,event,worker,prefork,mpmt_os2。
在linux(centos)下使用#http –l 命令可以查看当前使用的工作模式。也可以使用#apachectl -l命令。
#http –l
#apachectl –l
看到的prefork.c,说明使用的prefork工作模式。
可以在编译的时候使用#–with-mpm=prefork对应的工作模式名称来修改工作模式。
beos工作模式(跟linux关系不大,或者暂时用不上)
在Beos系统上的工作模式,使用一个单独的控制线程来创建和控制处理请求的工作线程。
event工作模式(不太稳定,或者说暂时用不上)
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中的配置信息。
*带井号的为注释部分
prefork模式的几个重要的参数:
名称
默认值
说明
StartServers
5
apache启动时候默认开始的进程数
MinSpareServers
5
最小的闲置进程数
MaxSpareServers
10
最大的闲置进程数
ServerLimit
256
最大的进程总数(参考,实际看MaxClients)
MaxClients
256
最大的进程总数
MaxRequestsPerChild
4000
每个进程处理的最多请求数
StartServers:这个看了就明白了。
MinSpareServers:举个例子就明白了。
apache在没有用户访问时候有5个闲置的进程,如果有一个用户访问网站。则闲置的进程就只有4个,这个值小于MinSpareServers,所以apache就以第一秒1个进程,第二秒2个进程,第三秒4个进程的速度新建空闲进程。直到大于等于MinSpareServers个空闲进程才结束。
MaxSpareServers:还是举个例子就明白了。
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个请求就要关闭这个进程呢?答案之一:为了防止内存的泄露。
下面图文介绍这些参数(要深刻理解一个知识就要亲自去体验)
测试环境参数
说明
操作系统
centos4.5(虚拟机)
服务器
apache2.2.6
内存
1G
服务器地址
192.168.212.128
客户端地址
192.168.212.1
测试文件index.php
<?php
for($i = 0;$i <= 10;$i++){
echo date('H:i:s',time());
echo '<br/>';
sleep(10);
}
?>
测试http.conf的prefork模式设置:(设置有点极端,但是可以很好的理解说明)
首先查看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为了处理用户请求而建立的进程详情)
当前为没有任何用户访问时候apache建立StartServers=1个进程
当有一个用户访问(通过本机上的ie浏览器访问虚拟主机上apache服务器模式该情景)
可以看到apache的进程增加为2个,为什么呢?当唯一的空闲进程时候完之后,空闲进程小于MinSpareServers,apache就从新建立一个进程。注意查看RSS值(该进程的内存使用量KB)为4424的空闲进程。
再看看访问完成之后的apache进程数。
可以看到还是只有两个进程,而且这两个进程都是空闲的。
当有两个用户访问(通过本机上的两个ie浏览访问虚拟主机上的apache服务器模拟该情景)
可以看到有两个用户访问的时候apache的进程数增加为3个。为什么呢?当本来空闲2个进程时候完之后,空闲进程小于MinSpareServers,apache就从新建立一个进程。注意查看RSS值(该进程的内存使用量KB)为4424的空闲进程。
再看看访问完成之后的apache进程数。
可以看到空闲的进程数又减少为2个。为什么呢?当两个用户访问完成之后两个用户的进程都会关闭,这时候就会有3个空闲进程,这个值大于MaxSpareServers=2的值。所以apache会自动关掉一个进程满足MaxSpareServers=2的值。
当有三个用户同时访问(通过本机上的三个ie浏览访问虚拟主机上的apache服务器模拟该情景)
可以看到apache的进程有3个,而这三个进程都在处理用户的请求,没有多余的空闲进程产生。为什么呢?因为在上面我们设置了MaxClients的值为3。所以apache最多只会生成3个进程。
再看看这三个用户访问完成之后的apache进程数。
可以看到空闲的进程数又减少为2个。为什么呢?当三个用户访问完成之后三个用户的进程都会关闭,这时候就会有3个空闲进程,这个值大于MaxSpareServers=2的值。所以apache会自动关掉一个进程满足MaxSpareServers=2的值。
当有四个用户同时访问(通过本机上的四个ie浏览访问虚拟主机上的apache服务器模拟该情景)
可以看到虽然有四个用户同时访问,但是apache创建的进程数还是只有3个。就是说apache只对前面的3个用户请求进行了处理。第4个用户只能等待。
这个时候查看apache的TCP连接情况。(对于TCP连接不太理解的可以点击查看)
可以看到这4个用户都已经建立了连接。但是apache只处理了前面的3个请求。处理完3个请求在处理最后一个请求,这点可能从文件的打印内容看到。四个用户几乎是同时访问的。
可以看到最后一个用户的请求时间是前面三个用户访问完成之后开始的。
依次类推,当有7个用户同时访问时候又是什么样的?只贴几张图,看了就明白了。
结论
如果从头到尾详细读过本篇文章,会得出如下的结论:
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,操作系统设定的超时时间内得不到相应才会断掉连接。
补充
本篇文章是本人对apache的工作模式,连接请求,并发等内容后总结的个人观点。难免会有些错误。
门面模式要求一个子系统的外部与其内部的通信必须通过一个统一的门面(Facade)对象进行。门面模式提供一个高层次的接口,使得子系统更易于使用。
在门面模式中,通常只需要一个门面类,并且此门面类只有一个实例,换言之它是一个单例类。当然这并不意味着在整个系统里只能有一个门面类,而仅仅是说对每 一个子系统只有一个门面类。或者说,如果一个系统有好几个子系统的话,每一个子系统有一个门面类,整个系统可以有数个门面类。
门面模式的角色:
1、门面角色:客户端可以调用这个角色的方法。此角色知晓相关的(一个或多个)子系统的功能和责任。
在正常情况下,本角色会将所有从客户端发来的请求委派到相应的子系统去。
2、子系统角色:可以同时有一个或者多个子系统。每一个子系统都不是一个单独的类,而是一个类的集合。
每一个子系统都可以被客户端直接调用,或者被门面角色调用。子系统并不知道门面的存在,对于子系统而言,
门面仅仅是另外一个客户端而已。
用户不需要和子系统内部打交道,只需要和门面进行接触就行,这样可以降低用户和子系统的依赖。
对于前端js,常用的类库都用到了门面模式,比如把对浏览器的兼容性封装在一个方法中,就是门面模式。
这个模式也比较简单

