并发的HTTP请求,apache是如何响应的,以及如何调用php文件的
链接:https://www.zhihu.com/question/23786410/answer/153455460
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
有一台正在运行的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 每个进程处理的最多请求数
----------------------------------------------------------------------------------------------------------------
(1)StartServers:这个看了就明白了。
(2)MinSpareServers:举个例子就明白了。
apache在没有用户访问时候有5个闲置的进程,如果有一个用户访问网站。则闲置的进程就只有4个,这个值小于MinSpareServers,所以apache就以第一秒1个进程,第二秒2个进程,第三秒4个进程的速度新建空闲进程。直到大于等于MinSpareServers个空闲进程才结束。
(3)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。
(4)ServerLimit:这个参数是控制apache的进程总数的,那为什么会有两个参数控制apache的进程总数呢?这个参数在apache1的时代是没有的,因为那个时候有个256M内存的服务器就很厉害了。后来apache2的时代到来,服务器的硬件也得到升级。很多服务器都是4G内存,还有很多比4G内存大的服务器出现。apache1的时代只有一个MaxClients参数控制进程总数就够了,而这个参数最大值是256定死了。但是到了apache2的时代必须调整ServerLimit值大于256才能使MaxClient支持大于256的值。
(5)MaxClients:apache最大的进程数。apache1的时代只有一个MaxClients参数控制进程总数就够了,而这个参数最大值是256定死了。但是到了apache2的时代必须调整ServerLimit值大于256才能使MaxClient支持大于256的值。
(6)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个进程
(1)当有一个用户访问(通过本机上的ie浏览器访问虚拟主机上apache服务器模式该情景)
可以看到apache的进程增加为2个,为什么呢?当唯一的空闲进程时候完之后,空闲进程小于MinSpareServers,apache就从新建立一个进程。注意查看RSS值(该进程的内存使用量KB)为4424的空闲进程。
再看看访问完成之后的apache进程数。
可以看到还是只有两个进程,而且这两个进程都是空闲的。
(2)当有两个用户访问(通过本机上的两个ie浏览访问虚拟主机上的apache服务器模拟该情景)
可以看到有两个用户访问的时候apache的进程数增加为3个。为什么呢?当本来空闲2个进程时候完之后,空闲进程小于MinSpareServers,apache就从新建立一个进程。注意查看RSS值(该进程的内存使用量KB)为4424的空闲进程。
再看看访问完成之后的apache进程数。
可以看到空闲的进程数又减少为2个。为什么呢?当两个用户访问完成之后两个用户的进程都会关闭,这时候就会有3个空闲进程,这个值大于MaxSpareServers=2的值。所以apache会自动关掉一个进程满足MaxSpareServers=2的值。
(3)当有三个用户同时访问(通过本机上的三个ie浏览访问虚拟主机上的apache服务器模拟该情景)
可以看到apache的进程有3个,而这三个进程都在处理用户的请求,没有多余的空闲进程产生。为什么呢?因为在上面我们设置了MaxClients的值为3。所以apache最多只会生成3个进程。
再看看这三个用户访问完成之后的apache进程数。
可以看到空闲的进程数又减少为2个。为什么呢?当三个用户访问完成之后三个用户的进程都会关闭,这时候就会有3个空闲进程,这个值大于MaxSpareServers=2的值。所以apache会自动关掉一个进程满足MaxSpareServers=2的值。
(4)当有四个用户同时访问(通过本机上的四个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,操作系统设定的超时时间内得不到相应才会断掉连接。
并发的HTTP请求,apache是如何响应的,以及如何调用php文件的的更多相关文章
- HTTP请求报文和HTTP响应报文
HTTP报文是面向文本的,报文中的每一个字段都是一些ASCII码串,各个字段的长度是不确定的.HTTP有两类报文:请求报文和响应报文. HTTP请求报文 一个HTTP请求报文由请求行(request ...
- HTTP请求报文和HTTP响应报文(转)
原文地址:http://blog.csdn.net/zhangliang_571/article/details/23508953 HTTP报文是面向文本的,报文中的每一个字段都是一些ASCII码串, ...
- Apache开启expires响应头,优化缓存
apache开始expires响应头输出 expires是什么 指示资源什么时候过期的时间值(GMT时间),在指定的过期时间前,浏览器可以直接使用自身缓存的版本,而不用向服务器发请求,大大减轻服务器压 ...
- http请求报文格式和响应报文格式
转载 出处 超文本传输协议(Hypertext Transfer Protocol,简称HTTP)是应用层协议.HTTP 是一种请求/响应式的协议,即一个客户端与服务器建立连接后,向服务器发送一个请求 ...
- python通过get,post方式发送http请求和接收http响应的方法,pythonget
python通过get,post方式发送http请求和接收http响应的方法,pythonget 本文实例讲述了python通过get,post方式发送http请求和接收http响应的方法.分享给大家 ...
- python通过get方式,post方式发送http请求和接收http响应-urllib urllib2
python通过get方式,post方式发送http请求和接收http响应-- import urllib模块,urllib2模块, httplib模块 http://blog.163.com/xyc ...
- HTTP请求格式和HTTP响应格式
主要内容: 1.HTTP请求格式 2.HTTP响应格式 一.HTTP请求格式 当浏览器向Web服务器发出请求时,它向服务器传递了一个数据块,也就是请求信息,HTTP请求信息由3部分组成:l 请求方 ...
- (转)HTTP请求报文和HTTP响应报文
原地址:http://www.cnblogs.com/biyeymyhjob/archive/2012/07/28/2612910.html HTTP报文是面向文本的,报文中的每一个字段都是一些ASC ...
- 发出HTTP请求并获得HTTP响应
发出HTTP请求并获得HTTP响应的过程如下: (1)定义HTTP请求HttpPut(HttpPost/HttpGet/HttpDelete)等: (2)定义各种Header,并加入HttpPut中: ...
- Django(十一)请求生命周期之响应内容(请求/响应 头/体)
https://www.cnblogs.com/renpingsheng/p/7534897.html Django请求生命周期之响应内容 http提交数据的方式有"post",& ...
随机推荐
- python记录_day11 闭包 迭代器
一.第一类对象: 函数名是一个变量,可以当普通变量使用,但它又是一个特殊的变量,与括号配合可以执行函数. 函数名的运用 1.单独打印是一个内存地址 2.可以给其他变量赋值 3.可以作为容器类变量的元素 ...
- centos7-jdk快速安装
安装之前先检查一下系统有没有自带open-jdk 命令: rpm -qa |grep java rpm -qa |grep jdk rpm -qa |grep gcj 如果没有输入信息表示没有安装. ...
- bat语法需要注意的地方
if else 格式 if exist C:\Python27 ::空格 ( ::(与if在同一行 ...
- MongoDB 第一篇
概述 MongoDB是一个高性能,开源,无模式的文档型数据库,使用C++开发.是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的.他支持的数据结构非常松散,是 ...
- Leetcode 999. 车的可用捕获量
999. 车的可用捕获量 显示英文描述 我的提交返回竞赛 用户通过次数255 用户尝试次数260 通过次数255 提交次数357 题目难度Easy 在一个 8 x 8 的棋盘上,有一个白色车(r ...
- Mybatis 查询tinyint(1)的数据库字段时会自动转换成boolean类型
解决方案:将字段的tinyint(1)变成tinyint(2)
- MongoDB文档的基本操作
1. MongoDB的安装方法 (1)下载MongoDB 相应的版本: (2)设置数据文件和日志文件的存放目录: (3)启动MongoDB服务: (4)将MongoDB作为服务启动. 2. Mongo ...
- Vuejs选项卡案例
css .active { color: red; border-bottom: 1px solid red; } ul li { padding: 0 15px; float: left; list ...
- centos7安装nginx 报./configure: error: C compiler cc is not found
CentOS 7 下 安装 nginx 执行配置命令 ./configure 时提示以下错误: 解决: 执行以下命令: yum -y install gcc gcc-c++ autoconf auto ...
- 【转】SQLServer汉字转全拼音函数
USE Test go IF OBJECT_ID('Fn_GetQuanPin','Fn') IS NOT NULL DROP FUNCTION fn_GetQuanPin go create fun ...