http://blog.csdn.net/goldlevi/article/details/7705160
之前和网络部门的人一起搭建我们的下载服务器,里面涉及了cache-control/expires的设置,之前每日更新也出现了文件无法下载的情况,最后发现是因为Lastmodified参数的值有变动。这里我把之前整理的与缓存有关系的HTTP头的资料和大家分享一下。
一、 基本知识:
先大概总结一下相关属性的含义。
1.Expires属性
Expires(过期时间)属性是HTTP控制缓存的基本手段,这个属性告诉缓存器:相关副本在多长时间内是新鲜的。过了这个时间,缓存器就会向源服务器发送请求,检查文档是否被修改。几乎所有的缓存服务器都支持Expires(过期时间)属性;大部分Web服务器支持用几种方式设置Expires属性;可以设计一个基于客户最后查看副本的时间(最后访问时间)或者根据服务器上文档最后被修改的时间的绝对时间间隔;Expires 头信息:对于设置静态图片文件(例如导航栏和图片按钮)可缓存特别有用;因为这些图片修改很少,你可以给它们设置一个特别长的过期时间,这会使你的网站对用户变得相应非常快;他们对于控制有规律改变的网页也很有用。
2.Cache-Control属性
HTTP 1.1介绍了另外一组头信息属性:Cache-Control响应头信息,让网站的发布者可以更全面的控制他们的内容,并定位过期时间的限制。
有 用的 Cache-Control响应头信息包括:
l max-age:执行缓存被认为是最新的最长时间。类似于过期时间,这个参数是基于请求时间的相对时间间隔,而不是绝对过期时间,值是一个数字,单位是秒:从请求时间开始到过期时间之间的秒数;
l s-maxage:类似于max-age属性,应用于共享(如:代理服务器)缓存;
l public:标记认证内容也可以被缓存,一般来说: 经过HTTP认证才能访问的内容,输出是自动不可以缓存的;
l no-cache:强制每次请求直接发送给源服务器,而不经过本地缓存版本的校验。这对于需要确认认证应用很有用(可以和public结合使用),或者严格要求使用最新数据 的应用(不惜牺牲使用缓存的所有好处);
l no-store:强制缓存在任何情况下都不要保留任何副本;
l must-revalidate:告诉缓存必须遵循所有你给予副本的新鲜度的,HTTP允许缓存在某些特定情况下返回过期数据,指定了这个属性,则告诉缓存,希望严格的遵循你的规则;
例如,如果你爱它一万年,请使用:
Cache-Control: max-age=315360000000, must-revalidate
3.Last-Modified/If-Modified-Since属性
这个属性提供了一种向服务器请求数据的方法。就是在发送请求的时候同时告诉服务器,我上次取的数据是什么时候的。如果数据从那时起没有改变,服务器将返回一个特殊的 HTTP 状态代码 304,这意味着 “从上一次请求后这个数据没有改变”。这一点有何进步呢?当服务器发送状态编码 304 时,不再重新发送数据。您仅仅获得了这个状态代码。所以当数据没有更新时,你不需要一次又一次地下载相同的数据。当然,服务器假定你有本地的缓存数据。
4. ETag/If-None-Match属性
ETag 是实现与最近修改数据检查同样的功能的另一种方法:没有变化时不重新下载数据。其工作方式是:服务器发送你所请求的数据的同时,发送某种数据的 hash (在 ETag 头信息中给出)。hash 的确定完全取决于服务器。当然,如果用最后修改时间当ETag,这个参数就和上面的属性一样了。
二、服务器配置方法
接下来,我们看一下下载服务器的apache设置。
# 利用目录进行区分 <VirtualHost *:80> <Directory "/home/admin/htdocs/"> ExpiresActive On ExpiresDefault "access plus 2 weeks" </Directory> <Directory "/home/admin/htdocs/uploads/"> ExpiresActive On ExpiresDefault "access plus 5 minutes" </Directory> ServerName download.wangwang.1688.com </VirtualHost> |
当然,apche提供了按文件进行不同配置的方法,可以更加精准:
# 利用文件类型进行区分 <ifmodule mod_expires.c> <filesmatch "\.(exe|zip)$ "> ExpiresActive on ExpiresDefault "access plus 2 weeks" </filesmatch> <filesmatch "\.(xml|html)$ "> ExpiresActive on ExpiresDefault "access plus 5 minutes" </filesmatch> </ifmodule> |
此外,我们的配置、升级和数据收集服务器采用的是NGINX部署方式,Nginx的配置方法和Apache类似:
# Nginx配置文件 location ~ .*\.(exe|zip)$ { expires 15d; } location ~ .*\.(xml|html)?$ { expires 1h; } |
ETag的配置方法是:
FileETag INode MTime Size
表明使用Inode、mtime和size这三个文件属性共同做为标识。
我们的下载文件,实际上是通过淘宝的CDN为用户提供下载。而我们这边有两台服务器做为下载源。也就是说当用户的请求到达CDN时,如果文件不存在或已过期,则CDN会来我们的服务器上获取。
先说说CDN。CDN 是构建在数据网络上的一种分布式的内容分发网。CDN的作用是采用服务器集群技术,克服单机系统输出带宽及并发能力不足的缺点,可极大提升系统支持的并发流数目,减少或避免单点失效带来的不良影响。CDN 利用全局负载均衡技术,将用户的访问指向离用户最近的工作正常的服务器上,由服务器直接响应用户的请求。服务器中如果没有用户要访问的内容,会根据配置自动从原服务器抓取相应的内容并提供给用户。
为了控制CDN到我们源服务器的访问压力,我们需要对文件进行缓存控制。针对旺旺安装包,由于我们每次发布都采用不同的版本号,下载路径例如http://download.wangwang.1688.com/AliIM2011_alitalk(6.60.33M).exe,因此,过期时间可以设置得很长,不会有影响。
针对每日更新的配置文件,我们每次更新都是同名更新,例如http://download.wangwang.1688.com/uploads/online/myt_du/default/6.60.33M.xml,客户端访问时始终会是这个地址,因此,过期时间就不能设置得太长。这里,安装包过期我们设置了2周,配置文件过期设置了5分钟。
如下图所示:
左侧发送的消息头中包含了if-modified-since,表明上次更新时间。右侧接收到的消息头中可以看出,网页内容没有过期,于是返回了304状态。浏览器则会自动从自己的缓存中返回上次获取的文件。而如果是自定义的访问函数,如果没有读取缓存的机制,则由于没有下载到内容,导致下载失败。不过,旺旺程序会比较服务器返回的LastModified时间,对于不比自己新的文件,也不会继续下载。当然,如果我们需要强制更新,把发送的请求包中Cache-Control设置为no-cache,那么服务器也会返回200状态码以及文件内容给我们。需要注意的是,上面的时间,都是GMT标准时间,会自动进行时区转换的。所以,在自己拼装消息头的时候要注意。
如有错误之处,请帮忙指出。谢谢。