Apache服务器性能
Apache服务器性能可以通过添加诸如RAM,更快的CPU等附加硬件资源来改善。但是,大多数情况下,通过服务器的自定义配置可以实现相同的结果。本文将探讨如何利用现有硬件资源(特别是Linux系统)从Apache获得最大性能。当然,假设有足够的硬件资源,特别是服务器不经常交换的足够的RAM。前两节介绍各种“编译时间”和“运行时”配置选项。运行时部分假定Apache是用 prefork MPM编译的。下面讨论HTTP压缩和缓存。最后,正在讨论使用单独的服务器来提供静态和动态内容。假设编译和配置Apache以及Linux的基本知识。2编译时配置选项
2.1仅加载必需的模块:
Apache HTTP Server是一个模块化程序,管理员可以通过选择一组模块来选择包含在服务器中的功能[ 2 ]。这些模块可以静态编译为httpd二进制文件,否则可以编译为动态共享对象(DSO)。 DSO模块可以在服务器构建时进行编译,也可以在以后使用 apxs实用程序进行编译和添加。模块mod_so必须静态编译到Apache内核以启用DSO支持。运行apache只需要所需的模块。 这减少了内存占用,从而降低了服务器性能。 静态编译模块将保存用于支持动态加载模块的RAM,但是每当要添加或删除模块时,必须重新编译Apache。 这是DSO机制方便的地方。 一旦mod_so模块被静态编译,任何其他模块可以使用httpd.conf文件中的LoadModule命令添加或删除 - 当然,如果在构建服务器时没有编译模块,那么您必须使用apxs来编译模块。
2.2选择合适的MPM:
Apache服务器附带多种多处理模块(MPM),负责绑定到机器上的网络端口,接受请求,并派遣子项来处理请求[ 3 ]。随时可以将一个MPM加载到服务器中。选择MPM取决于各种因素,例如操作系统是否支持线程,内存可用,可扩展性与稳定性,是否使用非线程安全的第三方模块等。Linux系统可以选择使用线程MPM像工作人员或非线程MPM,如prefork :
工作人员MPM使用多个子进程。 每个子进程都是多线程的,每个线程处理一个连接。 工作人员快速高度可扩展,内存占用比较低。 它非常适合多个处理器。 另一方面,工作者对错误的模块的容忍程度较低,故障线程可能影响子进程中的所有线程。
Prefork MPM使用多个子进程,每个子进程一次处理一个连接。 前叉非常适合单CPU或双CPU系统,速度与工作人员相当,高度容忍错误的模块和崩溃的孩子。 但是内存使用量很高,流量越多,内存使用量就越多。
3个运行时配置选项
3.1 DNS查找:
HostnameLookups指令启用DNS查找,以便可以记录主机名而不是IP地址。 这会增加每个请求的延迟,因为DNS查询必须在请求完成之前完成。 默认情况下,Apache 1.3及更高版本中的HostnameLookups为关闭。 将其关闭,并使用诸如logresolve之类的后处理程序来解析Apache访问日志文件中的IP地址。 Logresolve附带Apache。
当从指令使用允许或拒绝时,请使用IP地址而不是域名或主机名。 否则执行双重DNS查找以确保域名或主机名不被欺骗。
3.2允许:
如果AllowOverride未设置为“None”,则Apache将尝试在其访问的每个目录中打开.htaccess文件(由AccessFileName指令指定)。例如:DocumentRoot /var/www/html
<Directory />
AllowOverride all
</Directory>
如果要求URI /index.html,Apache将尝试打开/.htaccess /var/.htaccess,/var/www/.htaccess和/var/www/html/.htaccess。 这些额外的文件系统查找增加了延迟。 如果特定目录需要.htaccess,那么单独启用该目录。
3.3 FollowSymLinks和SymLinksIfOwnerMatch:
如果设置了FollowSymLinks选项,则服务器将跟随此目录中的符号链接。如果设置了SymLinksIfOwnerMatch,则只有当目标文件或目录由与该链接相同的用户拥有时,服务器才会遵循符号链接。如果设置了SymLinksIfOwnerMatch,那么Apache将不得不发出额外的系统调用,以验证链接的所有权和目标文件是否匹配。 当没有设置FollowSymLinks时,还需要额外的系统调用。 例如:
DocumentRoot /vaw/www/html对于针对URI /index.html的请求,Apache将在/ var,/ var / www,/ var / www / html和/var/www/html/index.html上执行lstat()。这些额外的系统调用将增加延迟。 lstat结果没有缓存,所以它们会在每个请求上发生。
<Directory />
Options SymLinksIfOwnerMatch
</Directory>
为了最大限度地提高性能,请在随处设置FollowSymLinks,从不设置SymLinksIfOwnerMatch。 否则,如果目录需要SymLinksIfOwnerMatch,那么请单独为该目录设置它。
3.4内容谈判:
避免内容协商以快速响应。 如果站点需要内容协商,请使用类型映射文件,而不是Options MultiViews指令。 使用MultiViews,Apache必须扫描目录中的文件,这增加了延迟。
3.5 MaxClients:
MaxClients为服务器可以支持的最大并发请求设置限制。没有超过这么多的子进程被产生。它不应该被设置得太低,以至于新的连接被放入队列中,这最终超时,服务器资源不被使用。设置太高将导致服务器开始交换,响应时间会大大降低。 MaxClients的适当值可以计算为:MaxClients =专用于Web服务器的总RAM /最大子进程大小---- [ 4 ]服务静态文件的子进程大小约为2-3M。对于PHP等动态内容,可能会在15M左右。 RSS列中"ps -ylC httpd --sort:rss"显示Apache进程的非交换物理内存使用量,以千字节为单位。
如果并发用户数量超过MaxClients,则根据ListenBacklog指令将请求排队到一个数字。 增加ServerLimit以将MaxClients设置为256以上。
3.6 MinSpareServers,MaxSpareServers和StartServers:
MaxSpareServers和MinSpareServers确定在等待请求时要保留的子进程数。 如果MinSpareServers太低,并且有一堆请求进来,那么Apache将不得不生成额外的子进程来提供请求。 创建子进程相对昂贵。 如果服务器正在忙于创建子进程,则它将无法立即提供客户端请求。 MaxSpareServers不应设置得太高,它可能导致资源问题,因为子进程消耗资源。
调整MinSpareServers和MaxSpareServers,使Apache每秒不需要频繁地超过4个子进程(Apache每秒最多可以共计32个子进程)。 每秒产生超过4个孩子时,会在ErrorLog中记录一个消息。
StartServers指令设置启动时创建的子服务器进程的数量。 Apache将继续创建子进程,直到达到MinSpareServers设置。 如果服务器不经常重启,对性能的影响不大。 如果有很多请求和Apache经常重启,请将其设置为相对较高的值。
3.7 MaxRequestsPerChild:
MaxRequestsPerChild指令设置单个子级服务器进程将处理的请求数量的限制。在MaxRequestsPerChild请求之后,子进程将会死机。默认设置为0,这意味着子进程永远不会过期。将其设置为几千的值是合适的。这可以帮助防止内存泄漏,因为进程在服务一定数量的请求后就会中断。不要设置太低,因为创建新进程确实有开销。3.8 KeepAlive和KeepAliveTimeout:
KeepAlive指令允许通过相同的TCP连接发送多个请求。这在为大量图像提供HTML页面时特别有用。如果KeepAlive设置为Off,则对于每个图像,必须单独的TCP连接。由于建立TCP连接而导致的开销可以通过打开KeepAlive来消除。KeepAliveTimeout确定等待下一个请求的时间。 将其设置为低值,可能在2-5秒之间。 如果设置得太高,处理的小孩被捆绑在等待客户端可用于为新客户端提供服务。
4 HTTP压缩和缓存
HTTP压缩在HTTP / 1.1中完全指定。服务器在发送到客户端之前,将gzip或deflate encoding方法用于响应有效负载。客户端然后解压缩有效载荷。所有主流浏览器都支持这一点,所以无需在客户端安装任何其他软件。使用压缩将节省带宽并提高响应时间,研究发现平均压缩增益为75.2%[ 5 ]。可以使用 mod_deflate模块在Apache中启用HTTP压缩。仅当浏览器请求压缩时,才能压缩有效载荷,否则将提供未压缩的内容。压缩感知浏览器通过HTTP请求头 - “Accept-Encoding:gzip,deflate”通知服务器它喜欢压缩的内容。然后服务器用压缩的有效载荷进行响应,响应头设置为“Content-Encoding:以下示例使用telnet查看请求和响应头:
gzip
bash-3.00$ telnet www.webperformance.org 80在缓存中,数据副本存储在客户端或代理服务器中,从而无需从服务器频繁地检索。这将节省带宽,减少服务器上的负载并减少延迟。缓存控制通过HTTP头完成。在Apache中,这可以通过 mod_expires和 mod_headers模块完成。还有服务器端缓存,其中经常访问的内容存储在内存中,以便可以快速地服务。模块 mod_cache可以用于服务器端缓存,它在Apache 2.2版本中是稳定的。
Trying 24.60.234.27...
Connected to www.webperformance.org (24.60.234.27).
Escape character is '^]'.
HEAD / HTTP/1.1
Host: www.webperformance.org
Accept-Encoding: gzip,deflate
HTTP/1.1 200 OK
Date: Sat, 31 Dec 2005 02:29:22 GMT
Server: Apache/2.0
X-Powered-By: PHP/5.1.1
Cache-Control: max-age=0
Expires: Sat, 31 Dec 2005 02:29:22 GMT
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 20
Content-Type: text/html; charset=ISO-8859-1
5为静态和动态内容分离服务器
服务动态内容的Apache进程大约需要3M到20M的RAM。 它增长以适应其服务的内容,并且不会减少,直到过程死亡。 说Apache进程增长到20M,以提供动态内容。 完成请求后,可以随意提供任何其他请求。 如果图像的请求进入,那么这个20M进程正在服务一个静态内容,这也可以由1M进程提供。 内存使用效率低下。
使用一个微小的Apache(最少的模块静态编译)作为前端服务器来提供静态内容。 请求动态内容转发到沉重的Apache(使用所有必需的模块进行编译)。 使用轻型前端服务器具有的优点是静态内容的服务速度快,无需内存使用,只有动态内容传递到重服务器。
可以通过使用mod_proxy和rewrite_module模块来实现请求转发。 假设有一个轻量级Apache服务器监听端口80,重量级Apache监听端口8088.然后,轻量级Apache中的以下配置可用于将除图像请求之外的所有请求转发到重型服务器。
ProxyPassReverse / http://%{HTTP_HOST}:8088/所有请求(图像除外)都被代理到后端服务器。响应由前端服务器接收,然后提供给客户端。就客户而言,所有的响应似乎来自于一个服务器。
RewriteEngine on ---- [9]
RewriteCond %{REQUEST_URI} !.*\.(gif|png|jpg)$
RewriteRule ^/(.*) http://%{HTTP_HOST}:8088/$1 [P]
6结论
配置Apache最大的性能是棘手的,没有硬而快的规则。了解Web服务器的要求,并尝试使用各种可用选项。使用像 ab和 httperf这样的工具测量Web服务器的性能。 tux , thttpd等轻量级服务器也可以用作前端服务器。如果使用数据库服务器,请确保已对其进行了优化,从而不会创建任何瓶颈。在MySQL的情况下,可以使用 mtop来监视缓慢的查询。通过使用PHP缓存产品(如 图尔克MMCache)可以提高PHP脚本的 性能 。它通过在编译状态下缓存PHP脚本来消除编译的开销。参考书目
1 http://news.netcraft.com/archives/web_server_survey.html
2 http://httpd.apache.org/docs/2.2/dso.html
3 http://httpd.apache.org/docs/2.2/mpm.html
4 http://modperlbook.org/html/ch11_01.html
5 http://www.speedupyoursite.com/18/18-2t.html
6 http://www.xs4all.nl/~thomas/apachecon/PerformanceTuning.html
7 http://www.onlamp.com/pub/a/onlamp/2004/02/05/lamp_tuning.html
8 http://httpd.apache.org/docs/2.2/misc/perf-tuning.html
9个Linux服务器Hacks由Rob Flickenger
作家生物: Vishnu Ram是MTech。 来自IIT Madras的通信系统。 他于2003年加入Bobcares ,自那时以来一直在为Poornam工作。