Apache HTTP服务器提高性能的教程

2018-09-12    来源:爱站科技

容器云强势上线!快速搭建集群,上万Linux镜像随意使用

  Apache是世界使用排名第一的Web服务器软件,下面就由爱站频道的小编分享一篇关于Apache HTTP服务器提高性能的教程给大家吧!大家可以参考一下哦!

  相比于Apache 1.3 ,2.0版本作了大量的优化来提升处理能力和可伸缩性,而且大多数的改进在默认状态下就可以生效。但是,在编译时和运行时,都有许多可以显著提高性能的选择。本文阐述在安装Apache2.0时,服务器管理员可以改善性能的各种方法。其中,部分配置选择可以使httpd更好地利用硬件和操作系统的兼容性,其他则是以功能换取速度。

  硬件和操作系统

  影响web服务器性能的最大的因素是内存。一个web服务器应该从不使用交换机制,因为交换产生的滞后使用户总感觉"不够快",所以用户就可能去按"停止"和"刷新",从而带来更大的负载。你可以,也应该,控制MaxClients的设置,以避免服务器产生太多的子进程而发生交换。这个过程很简单:通过命令计算出每个Apache进程平均消耗的内存,然后再为其它进程留出足够多的内存。

  其他因素就很普通了,装一个足够快的CPU,一个足够快的网卡,几个足够快的硬盘,这里说的"足够快"是指能满足实际应用的需求。

  操作系统是很值得关注的又一个因素,已经被证实的很有用的经验有:

  *

  选择能够得到的最新最稳定的版本并打好补丁。近年来,许多操作系统厂商都提供了可以显著改善性能的TCP协议栈和线程库。

  *

  如果你的操作系统支持sendfile()系统调用,则务必安装带有此功能的版本或补丁(对Linux来说,就是使用Linux2.4或更高版本,对Solaris8的早期版本,则需要安装补丁)。在支持sendfile的系统中,Apache2可以更快地发送静态内容而且占用较少的CPU时间。

  运行时的配置

  相关模块 相关指令

  * mod_dir

  * mpm_common

  * mod_status

  * AllowOverride

  * DirectoryIndex

  * HostnameLookups

  * EnableMMAP

  * EnableSendfile

  * KeepAliveTimeout

  * MaxSpareServers

  * MinSpareServers

  * Options

  * StartServers

  HostnameLookups 和其他DNS考虑

  在Apache1.3以前的版本中,HostnameLookups默认被设为 On 。它会带来延迟,因为对每一个请求都需要作一次DNS查询。在Apache1.3中,它被默认地设置为 Off 。如果需要日志文件提供主机名信息以生成分析报告,则可以使用日志后处理程序logresolve ,以完成DNS查询,而客户端无须等待。

  推荐你最好是在其他机器上,而不是在web服务器上执行后处理和其他日志统计操作,以免影响服务器的性能。

  如果你使用了任何"Allow from domain"或"Deny from domain"指令(也就是domain使用的是主机名而不是IP地址),则代价是要进行两次DNS查询(一次正向和一次反向,以确认没有作假)。所以,为了得到最高的性能,应该避免使用这些指令(不用域名而用IP地址也是可以的)。

  注意,可以把这些指令包含在段中使之局部化。在这种情况下,只有对这个区域的请求才会发生DNS查询。下例禁止除了.html和.cgi以外的所有DNS查询:

  HostnameLookups off

  HostnameLookups on

  如果在某些CGI中偶尔需要DNS名称,则可以调用gethostbyname来解决。

  FollowSymLinks 和 SymLinksIfOwnerMatch

  如果网站空间中没有使用 Options FollowSymLinks ,或使用了 Options SymLinksIfOwnerMatch ,Apache就必须执行额外的系统调用以验证符号连接。文件名的每一个组成部分都需要一个额外的调用。例如,如果设置了:

  DocumentRoot /www/htdocs

  Options SymLinksIfOwnerMatch

  在请求"/index.html"时,Apache将对"/www"、"/www/htdocs"、"/www/htdocs/index.html"执行lstat()调用。而且lstat()的执行结果不被缓存,因此对每一个请求都要执行一次。如果确实需要验证符号连接的安全性,则可以这样:

  DocumentRoot /www/htdocs

  Options FollowSymLinks

  Options -FollowSymLinks +SymLinksIfOwnerMatch

  这样,至少可以避免对DocumentRoot路径的多余的验证。注意,如果Alias或RewriteRule中含有DocumentRoot以外的路径,那么同样需要增加这样的段。为了得到最佳性能,应当放弃对符号连接的保护,在所有地方都设置FollowSymLinks ,并放弃使用SymLinksIfOwnerMatch 。

  AllowOverride

  如果网站空间允许覆盖(通常是用.htaccess文件),则Apache会试图对文件名的每一个组成部分都打开.htaccess ,例如:

  DocumentRoot /www/htdocs

  AllowOverride all

  如果请求"/index.html",则Apache会试图打开"/.htaccess"、"/www/.htaccess"、"/www/htdocs/.htaccess"。其解决方法和前面所述的 Options FollowSymLinks 类似。为了得到最佳性能,应当对文件系统中所有的地方都使用 AllowOverride None 。

  内容协商

  实践中,内容协商的好处大于性能的损失,如果你很在意那一点点的性能损失,则可以禁止使用内容协商。但是仍然有个方法可以提高服务器的速度,就是不要使用通配符,如:

  DirectoryIndex index

  而使用完整的列表,如:

  DirectoryIndex index.cgi index.pl index.shtml index.html

  其中最常用的应该放在前面。

  还有,建立一个明确的type-map文件在性能上优于使用"Options MultiViews",因为所有需要的信息都在一个单独的文件中,而无须搜索目录。请参考内容协商文档以获得更详细的协商方法和创建type-map文件的指导。

  内存映射

  在Apache2.0需要搜索被发送文件的内容时,比如处理服务器端包含时,如果操作系统支持某种形式的mmap() ,则会对此文件执行内存映射。

  在某些平台上,内存映射可以提高性能,但是在某些情况下,内存映射会降低性能甚至影响到httpd的稳定性:

  *

  在某些操作系统中,如果增加了CPU,mmap还不如read()迅速。比如,在多处理器的Solaris服务器上,关闭了mmap ,Apache2.0传送服务端解析文件有时候反而更快。

  *

  如果你对作为NFS装载的文件系统中的一个文件进行了内存映射,而另一个NFS客户端的进程删除或者截断了这个文件,那么你的进程在下一次访问已经被映射的文件内容时,会产生一个总线错误。

  如果有上述情况发生,则应该使用 EnableMMAP off 关闭对发送文件的内存映射。注意:此指令可以被针对目录的设置覆盖。

  Sendfile

  在Apache2.0能够忽略将要被发送的文件的内容的时候(比如发送静态内容),如果操作系统支持sendfile() ,则Apache将使用内核提供的sendfile()来发送文件。

  在大多数平台上,使用sendfile可以通过免除分离的读和写操作来提升性能。然而在某些情况下,使用sendfile会危害到httpd的稳定性

  *

  一些平台可能会有Apache编译系统检测不到的有缺陷的sendfile支持,特别是将在其他平台上使用交叉编译得到的二进制文件运行于当前对sendfile支持有缺陷的平台时。

  *

  对于一个挂载了NFS文件系统的内核,它可能无法可靠的通过自己的cache服务于网络文件。

  如果出现以上情况,你应当使用"EnableSendfile off"来禁用sendfile 。注意,这个指令可以被针对目录的设置覆盖。

  进程的建立

  在Apache1.3以前,MinSpareServers, MaxSpareServers, StartServers的设置对性能都有很大的影响。尤其是为了应对负载而建立足够的子进程时,Apache需要有一个"渐进"的过程。在最初建立StartServers数量的子进程后,为了满足MinSpareServers设置的需要,每一秒钟只能建立一个子进程。所以,对一个需要同时处理100个客户端的服务器,如果StartServers使用默认的设置5,则为了应对负载而建立足够多的子进程需要95秒。在实际应用中,如果不频繁重新启动服务器,这样还可以,但是如果仅仅为了提供10分钟的服务,这样就很糟糕了。

  " 一秒钟一个"的规定是为了避免在创建子进程过程中服务器对请求的响应停顿,但是它对服务器性能的影响太大了,必须予以改变。在Apache1.3中,这个 "一秒钟一个"的规定变得宽松了,创建一个进程,等待一秒钟,继续创建第二个,再等待一秒钟,继而创建四个,如此按指数级增加创建的进程数,最多达到每秒 32个,直到满足MinSpareServers设置的值为止。

  从多数反映看来,似乎没有必要调整MinSpareServers, MaxSpareServers, StartServers 。如果每秒钟创建的进程数超过4个,则会在ErrorLog中产生一条消息,如果产生大量此消息,则可以考虑修改这些设置。可以使用mod_status的输出作为参考。

  与进程创建相关的是由MaxRequestsPerChild引发的进程的销毁。其默认值是"0",意味着每个进程所处理的请求数是不受限制的。如果此值设置得很小,比如30,则可能需要大幅增加。在SunOS或者Solaris的早期版本上,其最大值为10000以免内存泄漏。

  如果启用了持久链接,子进程将保持忙碌状态以等待被打开连接上的新请求。为了最小化其负面影响,KeepAliveTimeout的默认值被设置为5秒,以谋求网络带宽和服务器资源之间的平衡。在任何情况下此值都不应当大于60秒,参见most of the benefits are lost。

  编译时的配置

  选择一个MPM

  Apache 2.x 支持插入式并行处理模块,称为多路处理模块(MPM)。在编译Apache时你必须选择也只能选择一个MPM,这里有几个针对非UNIX系统的MPM:beos, mpm_netware, mpmt_os2, mpm_winnt。对类UNIX系统,有几个不同的MPM可供选择,他们都会影响到httpd的速度和可伸缩性:

  * workerMPM使用多个子进程,每个子进程中又有多个线程。每个线程处理一个请求。该MPM通常对高流量的服务器是一个不错的选择。因为它比preforkMPM需要更少的内存且更具有伸缩性。

  * preforkMPM使用多个子进程,但每个子进程并不包含多线程。每个进程只处理一个链接。在许多系统上它的速度和workerMPM一样快,但是需要更多的内存。这种无线程的设计在某些情况下优于workerMPM:它可以应用于不具备线程安全的第三方模块(比如php3/4/5),且在不支持线程调试的平台上易于调试,而且还具有比workerMPM更高的稳定性。

  关于MPM的更多内容,请参考其文档。

  模块

  既然内存用量是影响性能的重要因素,你就应当尽量去除你不需要的模块。如果你将模块编译成DSO ,取消不必要的模块就是一件非常简单的事情:注释掉LoadModule指令中不需要的模块。

  如果你已经将模块静态链接进Apache二进制核心,你就必须重新编译Apache并去掉你不想要的模块。

  增减模块牵涉到的一个问题是:究竟需要哪些模块、不需要哪些模块?这取决于服务器的具体情况。一般说来,至少要包含下列模块:mod_mime, mod_dir, mod_log_config 。你也可以不要mod_log_config ,但是一般不推荐这样做。

  原子操作

  一些模块,比如mod_cache和worker使用APR(Apache可移植运行时)的原子API。这些API提供了能够用于轻量级线程同步的原子操作。

  默认情况下,APR在每个目标OS/CPU上使用其最有效的特性执行这些操作。比如许多现代CPU的指令集中有一个原子的比较交换(compare-and -swap, CAS)操作指令。在一些老式平台上,APR默认使用一种缓慢的、基于互斥执行的原子API以保持对没有CAS指令的老式CPU的兼容。如果你只打算在新式的CPU上运行Apache,你可以在编译时使用 --enable-nonportable-atomics 选项:

  ./buildconf

  ./configure --with-mpm=worker --enable-nonportable-atomics=yes

  --enable-nonportable-atomics 选项只和下列平台相关:

  * SPARC上的Solaris

  默认情况下,APR使用基于互斥执行的原子操作。如果你使用 --enable-nonportable-atomics 选项,APR将使用SPARC v8plus操作码来加快基于硬件的CAS操作。注意,这仅对UltraSPARC CPU有效。

  * x86上的Linux

  默认情况下,APR在Linux上使用基于互斥执行的原子操作。如果你使用 --enable-nonportable-atomics 选项,APR将使用486操作码来加快基于硬件的CAS操作。注意,这仅对486以上的CPU有效。

  mod_status 和 "ExtendedStatus On"

  如果Apache在编译时包含了mod_status ,而且在运行时设置了"ExtendedStatus On",那么Apache会对每个请求调用两次gettimeofday()(或者根据操作系统的不同,调用times())以及(1.3版之前)几个额外的time()调用,使状态记录带有时间标志。为了得到最佳性能,可以设置"ExtendedStatus off"(这也是默认值)。

  多socket情况下的串行accept

  警告

  这部分内容尚未完全根据Apache2.0中的变化进行更新 。一些信息依然有效,使用中请注意。

  这里要说的是 Unix socket API 的一个缺点。假设web服务器使用了多个Listen语句监听多个端口或者多个地址,Apache会使用select()以检测每个socket是否就绪。select()会表明一个socket有零或至少一个连接正等候处理。由于Apache的模型是多子进程的,所有空闲进程会同时检测新的连接。一个很天真的实现方法是这样的(这些例子并不是源代码,只是为了说明问题而已):

  for (;;) {

  for (;;) {

  fd_set accept_fds;

  FD_ZERO (&accept_fds);

  for (i = first_socket; i

  以上就是关于Apache HTTP服务器提高性能的教程,想必都了解了吧,更多相关内容请继续关注爱站技术频道。

标签: dns dns查询 http服务器 linux swap web服务器 安全 代码 服务器 服务器端 服务器管理 服务器使用 服务器性能 排名 搜索 网络 域名

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点!
本站所提供的图片等素材,版权归原作者所有,如需使用,请与原作者联系。

上一篇:在Linux架设代理服务器的操作方法

下一篇:如何在Linux架设透明网关?