一次Apache性能优化
kevin.Zhu 发布于:2013-10-1 0:21 分类:Apache 有 15 人浏览,获得评论 0 条
在keep-alive一节,尝试优化apache的线程数的时候,我一直带着两个疑问:一是为何我的进程占用内存高达100M之多;而是apache的线程数设置如何优化。还理解这一点,还得从apache mpm认识起。
认识MPM
多路处理模块(MPM)是Apache2.x起支持的插入式并行处理模块,意在使Apache能在不同的平台和不同的环境实现最优效率。按官网的介绍,其带来两个重要的好处:
常见的MPM:
prefork : 官网称其,是在"要求每个请求相互独立的情况"下表现最好的web服务器,其具有较强的自我调节能力,且仅需很少的配置指令就能得到较优的结果。关键设置MaxClients,这个值既要足够大到以处理潜在的请求高峰,同时又不能造成内存溢出(具体优化后面介绍)。
worker : 意在使网络服务器支持混合的多线程多进程,相比prefork的无线程,其利用了线程低开销的特点支持更大量的请求,不过其兼容性与可靠性弱于prefork,关键配置为ThreadsPerChild。值得注意的是,在worker模型下,子进程由为数不多的父进程建立,同时每个子进程可以建立ThreadsPerChild数量的线程和一个监听线程。
查看目前httpd的工作模式?
Compiled in modules:
表示apache当前的工作模式为prefork
配置工作模式:
apache默认支持prefork模型,需要支持worker mpm,需要在安装时指定
我们的Prefork模式
对于一般的企业级应用,基于稳定性考虑,大多选择这一模式。
缺省配置
配置说明:
StartServers设定perfork启动时创建事务进程数量。
MinSpareServers,设定了最小的空闲进程数,也就是apache会一直保留这个数量的进程,哪怕它空闲了也不会被销毁。其创建的过程很有意思:perfork先创建一个进程,并在等待一秒后再创建两个进程,下一秒4个、再下一秒16个、最后32个(指数级)。并以后一直保持每秒创建32个进程的速度,直到满足MinSpareServers为止。
相对的,MaxSpareServers设定了最大的空闲进程数,防止资源的浪费。当MaxSpareServers < MinSpareServers时,Apache会自动将其调整为MinSpareServers+1。值得注意的是,保持一定数量的MinSpareServers是很有必要的,因为其可以减少请求到来时apache fork新进程的开销,但同时过多空闲进程数也会占用资源。
MaxRequestsPerChild意味着进程处理多少个请求后将自动销毁,0意味着无限,即永不销毁。负载较高时,为使每个进程处理更过的请求,避免销毁、创建线程的开销,一般建议设定这个值为0或较大的数字。但是要注意即使负载降低后,MaxRequestsPerChild也会造成进程占用的内存无法释放,造成"负载降低,但是系统开销居高不下的局面"。
MaxClients设定Apache可同时处理的请求数量,其对Apache性能的影响非常大。默认的150远远不能满足一般站点(ps -ef|grep httpd|wc -l),超过这个数量的请求需要排队,直到前面的请求处理完毕。如果你的系统资源还剩很多,但是HTP访问却很缓慢,大多时候增加这个值将是问题得到缓解。理论上,这个值越多,其处理的请求也就越多,当然你的系统资源得支持,可是我不明白,为什么apache将这个值限定为256。幸好Apche也意识到这个问题,提供了一个ServerLimit指令来加大MaxClients。
线程数优化
Prefork优化的关键在于MaxClients与MaxRequestsPerChild。
MaxClients
最佳的值:
计算httpd平均占用内存
108468
(结果单位为KB)
显示每个进程占用了大约100M的内存,假设机器内存为32G,可拿出16G用于Apache。代入公式,得出
所以MaxClients可以设置为464
MaxRequestsPerChild
MaxRequestsPerChild是仅次于MaxClients的重要的配置,这个值大了影响资源的释放,小了apache不断的fork新的进程,增加CPU资源的开销。有时其影响不限于apache本身的资源,还有相关外部资源的释放。比如网站大多采用apache pool管理数据库连接,MaxRequestsPerChild过大就会造成数据库连接的资源迟迟不释放,给数据库带来不寻常的压力。
关于这一点,最典型的就是数据库出现tomieout等超时连接错误,重启Apache以后,即使访问量恢复到峰值,数据库仍然表现毫无压力,但是持续较长时间后,又出现同样的超时异常。
我采取一分钟pv/MaxClients得到这个值。
查看优化结果
可以实时查看apache线程状态来查看优化结果,执行指令
结果:
Apche TCP连接状态描述:
由于设置了keep-alive,且时间过长,为2分钟,所以上述结果有很多的CLOSE_WAIT进程。我们也可以使用上述的结果作为优化的输入。
进程内存优化
- 优化方法一
除掉多余的模块
108468
结果有100M之多,这是不大正常的,所以我尝试检查加载的module
Loaded Modules:
core_module (static)
mpm_prefork_module (static)
http_module (static)
so_module (static)
auth_basic_module (shared)
auth_digest_module (shared)
...
Syntax OK
剔除无用的模块后
重启后,显示内存102468,没有明显变化。
- 优化方法二
MaxRequestsPerChild
上述的优化,情况没有明显改善,对于一个仅有小部分的图片、js与小量数据查询的应用,一个进程平均占用102468的内存不合理。联想到MaxRequestsPerChild可能有影响,别忘了,除非进程处理request的数量超过这个值,不然资源不会被释放。查看http.conf。确定这个值为0,将这个值改为400。光滑重启
再次查看内存,仅有12916.8。