Apache性能优化
Apache是目前Internet上使用最为广泛的Web服务器。它具有比商业Web服务器不遑多让的功能与速度,同时安装与设置也十分简单,正是这些特性让它成为市场占有率最高的Web服务器软件。不过Apache安装简单,并不意味着简单地安装就可以适用于绝大多数应用环境,在高负荷的Web站点,Apache还需要进行调整、优化......
优化方法
Apache的配置文件是httpd.conf。Windows下该文件位于Apache安装目录的Conf子目录下,RedHatEnterpriseLinuxAS3.0Update2位于/etc/httpd/conf。通过调整该文件的某些参数,可以优化Apache的运行效率。
为了验证后文Apache参数的调整是否起作用,我们通常用Apache附带的ab(ApacheBench)对其进行压力测试。
ab最常用的语法格式是这样的:
ab-nXXX-cYYY-khttp://hostname.port/path/filename
其中:
-nXXX:
表示最多进行XXX次测试。也就是下载filename文件XXX次。
-cYYY:
客户端并发连接个数。
-k:
启用HTTPKeepAlive功能。默认不启用KeepAlive功能。
比如我们要对http://hostname:port/file.com下载10000次进行测试,并发访问为60个,启用HTTPKeepAlive功能,则访问指令为:
ab-n10000-c60-khttp://hostname:port/file.htm
测试平台
在本次优化过程中。笔者采用了两台电脑进行压力测试。其中一台为客户端,运行ab发送请求,另外一台为服务器,安装有Apache提供Web服务。
1.服务器配置
服务器端,笔者采用了较低端的配置。这样更容易通过ab测试看来调整参数后的效果:
CPU:IntelCeleron1.0GHz
内存:512MBSRAM100MHz
硬盘:Maxtor4D040H2
网卡:D-LinkDFE530TX
服务器端笔者安装两种操作系统:WindowsServer2003EnterpriseEdition并升级到最新的Hotfix。Apache服务器版本为2.0.50;或者RedHatEnterpriseLinuxAS3.0Update2。
2.客户端配置
为了使评测的瓶颈不在客户端,笔者客户端配置要比服务器端好,具体硬件配置如下:
CPU:P43.0GHz533MHz打开了HT支持
内存:512MBDDR400
硬盘:WD1200JB-00CRA1
网卡:D-LinkDFE530TX
客户端安装有RedHatEnterpriseLinuxAS3.0Update2。并利用其中的ab来进行性能测试。
通用优化技巧
对于Apache服务器来说,为了提高性能需要进行的某些参数调整具有通用性,也就是说只要采用了就可以使其性能更好。
1.关闭DNS和名字解析
*HostnameLookupson|off|double
Apache1.3之前HostnameLookups默认是打开的。这样客户端在访问服务器时,服务器将要解析客户端的主机名,并将其保存在日志文件中。对客户端进行域名反向解析会大幅降低服务器速度,所以最好将其设置为Off。关闭指令如下:
HostnameLookupsoff
*UseCanonicalNameon|off|dns
打开UseCanonicalName是Web服务器的标准做法。这是因为客户发送的大部分请求都是对本服务器的引用,打开该项设置就能使用ServerName和Port选项的设置内容构建完整的URL。如果将这个参数设置为Off,那么Apache将使用从客户请求中获得服务器名字和端口值,重新构建URL。
如果你不需要在Apache中架设虚拟主机,建议设置为:
UseCanonicalNameon
2.关闭多余模块
Apache采用了模块化设计,管理员可以有选择地加载一些模块来加强服务器的功能。这些模块,可以在创建服务器时静态编译到服务器的二进制代码中,也可以编译成一些独立服务器程序的DynamicSharedObjects(DSO)文件,在Apache启动的时候根据需要,动态加载。事实证明,不加载多余的模块总是可以提高Apache的性能。
Apache的DSO模块是在httpd.conf中以:
LoadModuleaccess_modulemodules/mod_access.so
方式加载。当不需要某个模块时,只要在其前添加“#”,注释掉该行。
一般来说,不需要加载以下模块:
mod_include.so:
服务器端包含,是一种已经过时的技术。
mod_autoindex.so:
如果不希望Apache列目录显示,可以删除。
mod_access.so、mod_auth.so:
如果你不需要进行安全验证,也没有必要加载。
最好加载以下模块:
mod_dir.so:
用于定义缺省文档index.php、index.jsp等。
mod_log_config.so:
用于定义记录文件格式。
mod_mime.so:
定义文件类型的关联。
最后需要说明一点的是,并不是加载所有的模块都会降低Apache性能。比如mod_zip可以把文件压缩之后再传给客户端,这样就可以减少40%左右的网络流量,而mod_expires则可以减少10%左右的重复请求。
3.取消.htaccess验证
除非你确定需要使用.htaccess文件来控制客户端对相应目录的访问权限,否则设置“AllowOverrideNone”,可以免除Apache在每个目录搜索.htaccess文件之苦。
4.取消符号链接
FollowSymLinks允许使用符号连接,这将使用浏览器有可能访问文档根目录(DocumentRoot)之外的内容,并且只有符号连接的目的与符号连接本身为同一用户所拥有时(SymLinksOwnerMatch),才允许访问,这个设置将增加一些安全性,但将耗费Apache大量的资源。
笔者建议:
OptionsFollowSymLinks
但是不要启用SymLinksOwnerMatch。
5.打开KeepAlive支持
在HTTP1.0中和Apache服务器的一次连接只能发出一次HTTP请求,而KeepAlive参数支持HTTP1.1版本的一次连接,多次传输功能,这样就可以在一次连接中发出多个HTTP请求。从而避免对于同一个客户端需要打开不同的连接。很多请求通过同一个TCP连接来发送,可以节约网络和系统资源。
在Apache的配置文件httpd.conf中,设置:
KeepAliveon
KeepAliveTimeout15
这样就能限制每个连接的保持时间是15秒。在我们的评测中发现,打开KeepAlive之前,ab测试的数据为:
Requestspersecond:201.32[#/sec](mean)
Timeperrequest:298.031[ms](mean)
Timeperrequest:4.967[ms](mean,acrossallconcurrentrequests)
Transferrate:839.49[Kbytes/sec]received
而打开KeepAlive支持之后,ab测试数据为:
Requestspersecond:341.70[#/sec](mean)
Timeperrequest:175.594[ms](mean)
Timeperrequest:2.927[ms](mean,acrossallconcurrentrequests)
Transferrate:1437.04[Kbytes/sec]received
最能反应Apache服务器性能的Requestspersecond,即每秒完成的请求次数从201.32提升到341.70,提升幅度为70%。虽然在现实环境中,不可能有这么多的同一连接发出的请求,但启用KeepAlive确实在一定程度上可以提高Apache服务器的吞吐量和反应速度。
另外,可以设置:
MaxKeepAliveRequests100
把MaxKeepAliveRequests设置的尽量大,可以在一次连接中进行更多的HTTP请求。但在我们的测试中还发现,把MaxKeepAliveRequests设置成1000,则评测的客户端容易出现“Sendrequesttimedout”的错误,所以具体数值还要根据自己的情形来设置。
参数决定性能
Apache除了可以通过一些常规方式进行优化外,还需要调整其运行参数,这样才能构建一个适合相应网络环境的Web服务。这些指令从两个级别对Apache进行了优化。
*进程级(Process-level)
进程级的参数用来控制Apache相应的客户端请求的进程数Process(在Windows下称之为线程数,threads)。
*协议级(Protocol-level)
协议级的指令则用来控制Apache与客户端的连接多久才自动断开。
由于Windows和Linux/UNIX设计原理的不同,所以进程级的指令根据Apache是工作在Linux/UNIX或者Windows下,而分成两种。
1.Linux下Apache性能优化
Linux下的Apache预设工作在prefork模式下(由每个进程处理连接请求),这种工作模式也是Apache1.3系列的工作模式。如果你需要其工作在其他模式下,则需要手工编译源代码来实现:
./configure--prefix=/usr/local/apache-2.0.50--with-mpm=worker--enable-include&&make&&makeinstall
Linux下进程级的Apache调整参数包括以下五个。
*StartServers
该参数决定Linux启动时,自动打开的Apache服务器的数目。它对Apache服务器的性能没有太大的影响。因为如果MinSpareServers设置的比较大,Apache服务器进程数会马上调整到不小于MinSpareServers的数目。
在Linux下,我们可以通过:
psaux|grephttpd
来查看当前打开的Apache服务进程数。
*MinspareServers
该参数用于配置在任何时候可用的最小Apache进程个数。一般情况下,当目前可用的Apache进程数不能满足需求时,Apache会自动打开新进程以服务客户。所以设置MinspareServers为较大的值只是为了让在比较繁忙的Web环境,让Apache可以尽快地满足客户端的访问需求。对于每天有百万访问量的网站来说,下面的数值是比较合适的:
MinspareServers32
*MaxSpareServers
较大的MinSpareServers可以保证Apache有较快的反应速度,过大的MinSpareServers又会占用更多的系统内存。如果你的系统内存不是很充足或者运行有其他的服务,把MaxSpareServers设置小一些可以为其他服务空出一些内存。当空闲Apache进程超过MaxSpareServers指定的数值时,Apache主进程会杀掉多余的空闲进程而保持空闲进程在MaxSpareServers指定的数值。
对于每天百万访问量的网站来说,配置大容量的内容,并且设置如下的值是比较合适的:
MaxSpareServers64
*MaxClients
服务器的处理能力毕竟是有限的,不可能同时处理无限多的连接请求。参数MaxClients就用于规定服务器支持的最多并发访问的客户数。
如果MaxClients设置得过大,系统在繁忙时不得不在过多的进程之间来回切换为更多的客户服务。这样对每个客户的反应就会变慢;如果设置得过小,系统繁忙时就会拒绝客户连接请求。
我们的设想原则是,当服务器性能较高时,可以适当增加这个值的设置。如果繁忙出现拒绝访问现象,说明需要升级服务器硬件了。
如果你不在意访问速度,或者认为反应速度慢也总比拒绝连接好,可以把该值设置大一些。
*MaxRequestsPerChild
当设置KeepAlive为off时,Apache服务器是用单独的子进程为一次连接服务,这样,每次连接都需要生成、关闭子进程,这些额外的操作浪费了计算机的大量处理能力。最好的方式是一个子进程可以为多次连接请求服务。
但子进程在接受访问请求时,需要不断地申请和释放内存,次数多了就会造成内存垃圾,影响系统稳定性。为了解决这个问题,可以规定每一个子进程处理的最大请求数,超过此数值,就让该子进程退出,再从原始的httpd进程中重新复制一个干净的副本,从而提高系统的稳定性。
第个子进程能够处理服务请求的最大次数由MaxRequestsPerChild定义。RedHatEnterpriseLinuxAS3.0Update2缺省的设置值为1000这个值比较适合(设置为0支持每个副本进行无限次的服务处理)。
在我们的测试过程中发现,RedHatEnterpriseLinuxAS3.0Update2下默认配置的Apache并不能很好地应付大负荷站点。我们需要打开KeepAlive,并加大StartServers、MinSpareServers、MaxSpareServers和MaxClients的数值。这些参数对于Apache性能的改善有很大的影响。
小知识:
RedHatEnterpriseLinuxAS3.0Update2最大MaxClients只能设置到256。如果你需要设置其为更高,需要在MaxClients前面添加:
ServerLimitxxx
其中xxx不能少于MaxClients的数值。该设置方法适用于Apache2.0系列。
2.Windows下Apache优化
Windows下,Apache2.0经过了全新的设计,采用多线程的方式(work)运行。这种运行方式,理论上比Linux/UNIX的Perfork运行模式有更好的性能。
Work模式下由单个控制进程负责子进程的建立。每个子进程可以建立由ThreadsPerChild指定的固定数量的线程。由独立的线程监听并处理到来的连接。
在Windows下可以执行“Apache-l”。查看当前工作模式,如果显示“mpm_winnt.c”,则表示Apache工作在多线程模式下;在Linux下执行“httpd-l”看到“prefork.c”表示工作在子进程模式下。
其配置语句是:
StartServers2
MaxClients150
MinSpareThreads25
MaxSpareThreads75
ThreadsPerChild25
MaxRequestsPerChild0
Apache力图维持一个备用的服务线程池,让客户端无须等待线程/进程的建立即可得到处理。最初建立的进程数由StartServers指定。然后Apache会不停地检测所有Apache进程中空闲线程的总数,并新建或结束进程使总数维持在MinSpareThreads和MaxSpareThreads所指定的范围以内。但同时可以得到处理的客户端的最大数量又取决于MaxClients指令,而进程建立的最大数量取决于ServerLimit指令。三者之间的关系为:
ServerLimit*ThreadsPerChild>=MaxClients