1、目的:
通过对大内存下Apache的配置优化使得内存利用率、性能提升最大化。
2、课题:
基本环境:
系统:首先大内存情况下我们默认最小“大内存”应超过4G,所以必须选择64bit CentOS。
内存:4G-8G
Apache版本:Apache 2.2
2.1 MPM(Multi -Processing Modules,多道处理模块):
Apache 2.X 系列最引人注目的就是MPM带来的性能改善。通过不同的MPM,Apache可以运行在一种多进程与多线程相混合的模式下,增强配置的可扩充性能。
通过 ./configure –help |grep mpm 我们可以知道当前的apache支持以下几种mpm:
Beos // BeOS系统默认mpm
mpmt_os2 // OS/2上缺省mpm
perchild // 被设计用作不同组不同身份的用户运行不同的子进程
leader、event 与 threadpool //均为worker变体,暂时还稳定,官方不推荐使用。
prefork //最常用的mpm之一
worker //最常用的mpm之一
Prefork:
如果不显式地在configure中加入—with-mpm,在linux默认安装的是prefork,
安装完apache后可以用httpd –l来查看安装的模块。缺省的httpd.conf文件中应该包含以下内容:
StartServers 5
MinSpareServers 5
MaxSpareServers 10
MaxClients 150
MaxRequestsPerChild 0
以上配置文件为Apache在启动的时候,在进程最初的时候建立5 (StartServers)个子进程后,为了满足MinSpareServers设置的10需要按指数级增加创建新的进程,例如创建1个进程,再创建2个进程,再创建4个进程,最高为32个/秒,直到满足 MinSpareServers设置的值为止。Prefork是预派生进程,可以不必在请求到来时再产生新的进程,从而减小了系统开销及增加性能。如果空闲进程数大于MaxSpareServers,Apache会自动kill掉一些多余进程。
每个prefork出来的httpd子进程在处理了“MaxRequestsPerChild”(默认0为无限.)个请求后进程将被系统自动回收。为了防止可能的内存溢出,应跟据服务器的负载来设定一个上限。
MaxClients设定了Apache同时处理的请求,此参数对apache性能的影响最大。通过pgrep httpd | wc -l,如果已经达到MaxClients设定值,设定值后的请求就要排队。Apache默认的限制不能大于256。在Apache 2.X系列中新加入了ServerLimit指令,无须重编译Apache就可以加大MaxClients。
StartServers 30
MinSpareServers 45
MaxSpareServers 45
ServerLimit 20000
MaxClients 20000
MaxRequestsPerChild 10000
ServerLimit的最大值是20000,如果一定要再加大这个值,在源码包里面找到server/mpm/prefork/prefork.c进行以下修改:
#define DEFAULT_SERVER_LIMIT 256
该参数即apache默认Maxclients的最大值,超过这个值apache不启动.
#define MAX_SERVER_LIMIT 20000
该参数即ServerLimit的最大值。其中Maxclients不能大于ServerLimit
worker:
worker是2.X 系列中全新的支持多线程和多进程混合模型的MPM。由于使用线程来处理,所以可以处理相对海量的请求,而系统资源的开销要小于基于进程的prefork的服务器。worker也使用了多进程,每个进程又生成多个线程,以获得基于进程服务器的稳定性。
在configure -with-mpm=worker安装完成后, httpd.conf缺省有以下配置:
StartServers 2
MaxClients 150
MinSpareThreads 25
MaxSpareThreads 75
ThreadsPerChild 25
MaxRequestsPerChild 0
由主控制进程生成“StartServers”个子进程,每个子进程中包含固定的ThreadsPerChild线程数。同样,为了不在请求到来时再生成线程,MinSpareThreads和MaxSpareThreads设置了最少和最多的空闲线程数,这两个参数并非像prefork的参数中那么重要,对性能的影响并不像prefork中那么明显,最大可以设置大75和150;
MaxClients设置了所有子进程中的线程总数。如果现有子进程中的线程总数不能满足负载,控制进程将派生新的子进程。
ThreadsPerChild是worker MPM中与性能相关最密切的指令。ThreadsPerChild的最大缺省值是64,如果负载较大,64也是不够的。这时要显式使用 ThreadLimit指令,它的最大缺省值是20000。上述两个值位于源码树server/mpm/worker/worker.c中的以下两行:
#define DEFAULT_THREAD_LIMIT 64
ThreadsPerChild
#define MAX_THREAD_LIMIT 20000
ThreadLimit
Worker模式下所能同时处理的请求总数是由子进程总数乘以ThreadsPerChild值决定的,应该大于等于MaxClients。如果负载很大,现有的子进程数不能满足时,控制进程会派生新的子进程。默认最大的子进程总数是16,加大时也需要显式声明ServerLimit(最大值是 20000)。这两个值位于源码树server/mpm/worker/worker.c中的以下两行:
#define DEFAULT_SERVER_LIMIT 16
#define MAX_SERVER_LIMIT 20000
StartServers 4
MaxClients 4000
ServerLimit 40
MinSpareThreads 50
MaxSpareThreads 200
ThreadLimit 400
ThreadsPerChild 100
MaxRequestsPerChild 10000
其中要满足
ServerLimit X ThreadsPerChild > MaxClients
MaxClients mod ThreadsPerChild = 0
2.2 细节配置:
Rewrite如果非必要尽量写在httpd-vhost.conf中,这样每次启动加载一次规则即可,开启.htaccess AllowOverride后,每次url请求都要遍历上级目录查找该文件,找到后导入,再加载。在访问量巨大的情况下,能节省一笔不小的性能开销。
服务器如图片较多,就直接开启keepalive。
3.总结:
在大内存下对apache性能上的提升主要还是在于mpm的选择和mpm的参数调试上。对于内存数应该具体通过各个mpm进行内存消耗计算,总消耗应不大于总内存。否则会导致内存溢出错误。
4.参考资料:
Apache MPM prefork:http://httpd.apache.org/docs/2.2/en/mpm.html
Apache 2.2 Model: http://httpd.apache.org/docs/2.2/mod/