缓存是在高速媒体(通常是SRAM或RAM)中临时存储频繁访问的数据,以便更有效地检索。Web缓存通过浏览器,代理或服务器缓存将经常使用的对象存储在离客户端较近的位置。通过将“新鲜”对象存储在离用户较近的位置,可以避免到原始服务器的往返,减少带宽消耗,服务器负载,最重要的是延迟。本文介绍如何配置Apache服务器以实现更高效的缓存,以节省带宽并提高性能。
缓存不仅适用于静态站点,甚至动态站点也可以从缓存中受益。图形和多媒体通常不会像(X)HTML文件那样频繁地更改。像徽标,标题和导航这样很少改变的图形可以被赋予更长的到期时间,而像XHTML和XML文件那样更频繁地更改的资源可以被赋予更短的到期时间。通过设计具有缓存的站点,您可以定位不同类别的资源,只需几行代码即可为它们提供不同的到期时间。
三种缓存方式
有三种方法可以为您的网站设置缓存控制规则。
- 通过
<meta>
标签(<meta http-equiv="Expires"...>
) - 通过设置HTTP头(CGI脚本等)以编程方式
- 通过Web服务器配置文件(httpd.conf)
本文介绍了通过服务器配置文件进行缓存控制的第三种方法。第一种方法适用于浏览器,但大多数中间代理服务器不解析HTML文件,它们寻找HTTP标头来设置缓存策略。的编程方式设置高速缓冲存储器控制头(第二个方法Expires
和CacheControl
例如)可以动态CGI脚本输出动态数据是有用的。
缓存新鲜度保证
为了缓存Web对象,源服务器上游的浏览器和代理服务器必须能够计算“新鲜度生命周期”,或者从先前访问或修改对象多长时间才能从缓存中显示。HTTP主要通过客户端,代理和源服务器之间的简短HTTP头对话来确定这个数字甜瓜是否正在挤压,以确定重用缓存对象是否可以,或者重新加载资源以获得新的资源。以下是我们徽标图片的REQUEST / RESPONSE序列示例l.gif
。
Host: www.websiteoptimization.com User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; rv:1.7.3) Gecko/20041001 Firefox/0.10.1 Accept: image/png,*/*;q=0.5 Accept-Language: en-us,en;q=0.5 Accept-Encoding: gzip,deflate Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 Keep-Alive: 300 Connection: keep-alive Referer: http://www.websiteoptimization.com/
我们的服务器响应如下:
HTTP/1.1 200 OK Date: Mon, 25 Oct 2004 11:55:45 GMT Server: Apache/1.3.31 Cache-Control: max-age=2592000 Expires: Wed, 24 Nov 2004 11:55:45 GMT Last-Modified: Sat, 19 Jun 2004 15:25:10 GMT ETag: "7b80d9-891-40d45ad6" Accept-Ranges: bytes Content-Length: 2193 Keep-Alive: timeout=15, max=99 Connection: Keep-Alive Content-Type: image/gif
此图片最后修改于6月19日,距离上次访问时间为30天。从这些响应标头中可以清楚地看出,此对象不会经常更改,并且可以安全地缓存长达一个月。在客户端向代理或源服务器查询特定对象之后,如果该对象被验证为仍然是新鲜的,则从缓存返回该对象。如果不是,则从原始服务器重新加载对象以获取新副本。
使用mod_expires和mod_headers进行缓存控制
对于Apache,mod_expires和mod_headers通过从服务器发送的HTTP头来处理缓存控制。由于默认情况下未安装它们,请让服务器管理员为您安装它们。对于Apache / 1.3x,通过将以下行添加到httpd.conf配置文件来启用expires和headers模块。
LoadModule expires_module libexec/mod_expires.so LoadModule headers_module libexec/mod_headers.so AddModule mod_expires.c AddModule mod_headers.c ... AddModule mod_gzip.c
请注意,加载顺序在Apache / 1.3x中很重要,mod_gzip必须在所有其他模块之后加载最后。
对于Apache / 2.0,请在httpd.conf文件中启用这样的模块。
LoadModule expires_module modules/mod_expires.so LoadModule headers_module modules/mod_headers.so LoadModule deflate_module modules/mod_deflate.so
mod_deflate是Apache / 2.0中的本机压缩模块(尽管mod_gzip在处理任意浏览器方面做得更好)。在这种情况下,加载顺序无关紧要,因为Apache / 2.0会为您处理此问题。
通过扩展目标文件进行缓存
为现有站点启用缓存控制标头的一种快速方法是按扩展名定位文件。虽然这种方法有一些缺点(特别是文件扩展的要求),但它具有简单的优点。要将mod_expires设置ExpiresActive
为on。
ExpiresActive On
接下来定位您网站的根HTML目录,以便一举为您的网站启用缓存。
<Directory "/home/website/public_html"> Options FollowSymLinks MultiViews AllowOverride All Order allow,deny Allow from all ExpiresDefault A300 <FilesMatch "\.html$"> Expires A86400 </FilesMatch> <FilesMatch "\.(gif|jpg|png|js|css)$"> Expires A2592000 </FilesMatch> </Directory>
ExpiresDefault A300
在访问(A)后将默认到期时间设置为300秒。使用M300会在文件修改后将到期时间设置为300秒。该FilesMatch
段将所有.html
文件的缓存控制标头设置为86400秒(1天)。第二FilesMatch
部分将所有图像,外部JavaScripts和CSS文件的缓存控制头设置为2592000秒(30天)。
请注意,您可以使用多个目录部分更精细地定位文件,如下所示:
<Directory "/home/website/public_html/images/logos/">
对于真正动态的内容,您可以通过设置零秒的年龄来强制不缓存资源,并且不将资源存储在任何位置。
<Directory "/home/website/cgi-bin/"> Header Set Cache-Control "max-age=0, no-store" </Directory>
按MIME类型定位文件
上述方法的缺点是依赖于文件扩展名的存在。在某些情况下,网站管理员选择使用无扩展名URL来实现可移植性和性能(请参阅使用内容协商重写URL)。更好的方法是使用ExpiresByType
mod_expires模块的命令。顾名思义,ExpiresByType
定位用于按MIME类型缓存的资源,就像这样。
ExpiresActive On ExpiresDefault "access plus 300 seconds" <Directory "/home/website/public_html"> Options FollowSymLinks MultiViews AllowOverride All Order allow,deny Allow from all ExpiresByType text/html "access plus 1 day" ExpiresByType text/css "access plus 1 day" ExpiresByType text/javascript "access plus 1 day" ExpiresByType image/gif "access plus 1 month" ExpiresByType image/jpg "access plus 1 month" ExpiresByType image/png "access plus 1 month" ExpiresByType application/x-shockwave-flash "access plus 1 day" </Directory>
此httpd.conf代码仅以更灵活和可读的方式设置相同的参数。对于到期命令,您可以使用access
或modified
取决于您是要从上次访问文件开始计数,还是上次修改文件。在我们针对WebSiteOptimization.com的案例中,我选择对可能发生变化的文本文件使用短访问偏移,并为不经常更改的图像使用较长的访问偏移。
注意AllowOverride All
命令。这允许网站管理员使用.htaccess文件覆盖这些设置,以进行基于目录的身份验证和重定向。但是,覆盖httpd.conf文件会导致性能下降,因为Apache必须遍历文档树以查找.htaccess文件。
HTTP标头结果
对于我们的Apache / 1.3x服务器,httpd.conf文件禁用了缓存控制。在更新httpd.conf配置文件之前,让我们看一下WebSiteOptimization.com主页和嵌入式徽标(l.gif)的标题。
HTTP/1.1 200 OK Date: Sat, 23 Oct 2004 23:15:38 GMT Server: Apache/1.3.31 (Unix) mod_gzip/1.3.26.1a mod_auth_passthrough/1.8 mod_log_bytes/1.2 mod_bwlimited/1.4 PHP/4.3.9 FrontPage/5.0.2.2634a mod_ssl/2.8.20 OpenSSL/0.9.7a Connection: close Content-Type: text/html Content-Encoding: gzip Content-Length: 4326 HTTP/1.1 200 OK Date: Sat, 23 Oct 2004 23:14:13 GMT Server: Apache/1.3.31 (Unix) mod_gzip/1.3.26.1a mod_auth_passthrough/1.8 mod_log_bytes/1.2 mod_bwlimited/1.4 PHP/4.3.9 FrontPage/5.0.2.2634a mod_ssl/2.8.20 OpenSSL/0.9.7a Last-Modified: Sat, 19 Jun 2004 15:25:21 GMT ETag: "7b80da-4f2-40d45ae1" Accept-Ranges: bytes Content-Length: 1266 Connection: close Content-Type: image/gif
使用上面基于MIME的代码更新httpd.conf文件后,我们使用以下命令重新启动HTTP守护程序:
service httpd restart
我们的主页和徽标的标题现在看起来像这样。
HTTP/1.1 200 OK Date: Sat, 23 Oct 2004 23:17:52 GMT Server: Apache/1.3.31 Cache-Control: max-age=86400 Expires: Sun, 24 Oct 2004 23:17:52 GMT Connection: close Content-Type: text/html Content-Encoding: gzip Content-Length: 4326 HTTP/1.1 200 OK Date: Sat, 23 Oct 2004 23:18:54 GMT Server: Apache/1.3.31 Cache-Control: max-age=2592000 Expires: Mon, 22 Nov 2004 23:18:54 GMT Last-Modified: Sat, 19 Jun 2004 15:25:21 GMT ETag: "7b80da-4f2-40d45ae1" Accept-Ranges: bytes Content-Length: 1266 Connection: close Content-Type: image/gif
这两种资源现在都有缓存控制头。另请注意,该Server
字段也被删除。这是通过以下ServerTokens
命令完成的:
ServerTokens Min
这最小化了响应头:
Server: Apache/1.3.31 (Unix) mod_gzip/1.3.26.1a mod_auth_passthrough/1.8 mod_log_bytes/1.2 mod_bwlimited/1.4 PHP/4.3.8 FrontPage/5.0.2.2634a mod_ssl/2.8.19 OpenSSL/0.9.7a
至
Server: Apache/1.3.31
我们的图像现在可以放置30天。但是HTML文件没有Last-Modified
标题。这是因为我们使用条件服务器端包含来为不同的浏览器合并不同的CSS来保存HTTP请求。我们将在未来的调整中解决SSI页面的可扩展性问题。
警告:Pragma no-cache已弃用
根据Gomez的Stephen Pierzchala的说法,你应该避免使用已弃用的Pragma no-cache标头。以下是INVALID服务器响应:
Header Set Pragma "no-cache"
“我在服务器响应中看到了很多。在HTTP规范中,Pragma标头是一个不推荐使用的客户端HTTP / 1.0请求标头。”
结论
服务器缓存控制可以在减少带宽费用的同时提高网站的性能。通过缓存不经常更改较长时间的对象,并将频繁更新的内容缓存较短时间(或根本不缓存),您可以加快感知的加载时间,同时保持新鲜内容。