标签响应报头值,一个实体标签,提供了一个"模糊"缓存验证器.这将允许在不便存 储修改信息的情况下进行可靠的确认,包括HTTP 日期数据不充足和源服务器不想因使用修改日期而带来麻烦的情况.
实体标签描述见3.11 节,有关其报头的描述 见14.19,14.24,14.26,14.44.
13.3.3 强,弱验证器
由于源服务器和缓存器会比较两个验证器来确定他们是否代 表相同的条目,所以通常
希望实体发生任何变化,验证器也相应变化,这样的验证器为强验证器.
同时还会有这样的情况,服务器倾向于仅在发生重要的语义变化时才改变验证器。在资
源变化时验证器未必变化的称为弱验证器.
ETag通常情况下是强验证,Last-Modified通常情况下是弱验证,但通过相应设置,其验证 强度属性将会改变。
Etag由于是强验证,其优先权高于Last-Modified。
当两类验证器同时存在时,必须两类条件都为真,否则仍然会从源服务器获取数据。
基于以上所述:缓存优先级或者前后顺序为:Max-Age > Expries > Etag > Last-Modified
这个优先级顺序是用户代理与源服务器处理缓存一个依据。值得注意的是ETag,虽然其为强验证, 但由于性能和同步问题,经常舍去不用,下面会详细讲到。
以上都是基于理论介绍,接下来简单的介绍下上文中涉及的各个报头,及其在服务器中的设置,以及出 现的问题及解决方案。
HTTP协议中各报头信息
Expries
Cache-Control
详见参考文档7
Last-Modified(详见参考 文档7)
文件最后修改时间。一般情况下可以理解为源服务器上文件的Last-Modified属性值。具 体实现和Web服务器以及资源(不仅仅是文件)属性有关。
Last-Modified由服务器端生成,客户端通过If-Modified-Since或者说If-Unmodified-Since这个条件判断请求 来验证资源是否修改。我们常见的是使用If-Modified-Since
ETag
实体值,可用于比较来自同一资源的不同实体。可以简单理解为资源的版本信息。
Etag主要为了解决Last-Modified无法解决的一些问题(详见参考文档7,11):
1、一些文件也许会周期性的更改,但是他的内容并不改变(仅仅 改变的修改时间),这个时候我们并不希望客户端认为这个文件被修改了,而重新GET;
2、某些文件修改非常频繁,比如在秒以下的时间内进行修改, (比方说1s内修改了N次),If-Modified-Since能检查到的粒度是s级的,这种修改无法判断(或者说UNIX记录MTIME只能精确到 秒)
3、某些服务器不能精确的得到文件的最后修改时间;
为此,HTTP/1.1引入了Etag(Entity Tags).Etag仅仅是一个和文件相关的标记,可以是一个版本标记,比如说v1.0.0或者说"2e681a-6-5d044840"这么一串看起来 很神秘的编码。
Etag 由服务器端生成,客户端通过If-Match或者说If-None-Match这个条件判断请求来验证资源是否修改。我们常见的是使用If-None- Match。HTTP/1.1虽然引入了ETag,但是并没有说明其具体生成规则,因此需要各服务器自己实现。但是不管怎样的算法,在服务器端都要进行计 算,都要进行比较,计算和比较就有开销,会带来性能损失。因此为了榨干这一点点性能,不少网站完全把Etag禁用了(比如YUI)。与此对应的是 HTTP/1.1鼓励服务器尽可能的开启Etag^_^
你如何选择要根据自己的实际情况。如果你选择了使用,那么恭喜你,还有下面一个问题需要解决。
问题:
当使用群集、负载均衡时,由于各文件最后更新时间,Web服务器设置等方面的差异,会造成相同实 体的ETag不同。并且由于HTTP协议规定,如果Etag和Last-Modified同时存在,则这两个条件必须同时满足才能返回304错误 ,否则会向源服务器发送获取实体的请求。
MSDN上说IIS5存在此问题,但在IIS6和后续版本中已经解决。(你最好尝试一下)
解决方法:
1. 使用一种机制使多 台服务器上的相同实体的Etag相同
2. 直接去掉Etag
IIS相关实现及设置
Expries
Cache-Control
有两种方法设置:
1. 使用IIS
IISà属性àHTTP头à自定义 HTTP头à添加
Cache-Control:max-age:3600
Expires:Mon, 09 Jul 2018 05:53:19 GMT
2. 使用 adsutil.vbs(详见参考文档2)
到IIS的AdminScripts目录下去找到adsutil.vbs文件。
cd C:\Inetpub\AdminScripts
比如我们要给根目录下的imags目录添加Expires/Cache-Control,首先要 在metabase中给它加一个节点cscript adsutil.vbs create W3SVC/1/root/images "IisWebVirtualDir"
设置images目录下的文件获得Cache-Control: max-age=60,就这样
csript adsutil.vbs set W3SVC/1/root/images/HttpExpires "D, 0x3c"
设置images目录下的文件获得“Expires: Thu 27 Nov 2008 07:00:00 GMT”,
csript adsutil.vbs set W3SVC/1/root/images/HttpExpires "S, Thu 27 Nov 2008 07:00:00 GMT"
使用Metabase
Explorer
也可以修改
Explorer
也可以修改
下载地址:
Last-Modified
这个基本不用更改,按默认生成的就好。
ETag
IIS对Etag的计算算法是ETag = {Filetimestamp:ChangeNumber}, Filetimestamp为文件时间戳,ChangeNumber是metabase的change number
解决多服务器ETag同步方法:
1. 使所有IIS的 ETag设置一致。
设置方法详见参考文档3,4
2. 去掉ETag
除了写ISAPI,暂时没有找到其他IIS下去掉ETag的方法。
Apache相关实现及设置
Expries:
Cache-Control
具体设置见参考文档1
Last-Modified
同IIS
ETag
生成机制为:文件的inode(索引节点)、大小、最后修改时间决定,通过配置可以决定使用哪些 要素来生成。具体配置详见参考文档10
解决多服务器ETag同步方法:
1. 去掉ETag
使用配置 FileETag none
Apache对Etag的判断流 程为:(详见参考文档11)
首先判断是不是弱Etag。
如果不是,进入下面的情况:
强Etag 根据配置文件中的配置来设置Etag值,默认的Apache的FileEtag设置为:FileEtag、INode、Mtime、Size,也就是根据 这三个属性来生成Etag值,他们之间通过一些算法来实现,并输出成hex的格式,相邻属性之间用-分隔,比如:Etag "2e681a-6-5d044840"。这里面的三个段,分别代表了INode,MTime,Size根据算法算出的值的Hex格式。
当然,我们可以改变Apache的FileEtag设置,比如设置成FileEtag Size,那么得到的Etag可能为:Etag "6"
总之,设置了几个段,Etag值就有几个段。(不要误以为Etag就是固定的3段式)
说明
这 里说的都是Apache 2.2里面的Etag实现,因为HTTP/1.1并没有规定Etag必须是什么样的实现或者格式,因此你也可以修改或者完全编写自己的算法得到Etag, 比如"2e681a65d044840",客户端会记住并缓存下这个Etag,下次访问的时候直接拿这个值去和服务器生成的Etag对比。
当其为弱校验(弱Etag)时,重新考虑前面提到的3个问题:
问题1、一些文件也许会周期性的更改,但是他的内容并不改变(仅仅改变的修改时间),这个时候我 们并不希望客户端认为这个文件被修改了,而重新GET;
解决办法:如果使用强Etag,每次得会要求重新GET页面,如果使用Etag,比方说设置成 FileEtag Size等,就可以忽略MTime造成的Last-Modified时间修改从而影响了If-Modified-Since(IMS)这个校验了。这点和 弱Etag无关。
问题2、某些文件修改非常频繁,比如在秒以下的时间内进行修改,(比方说1s内修改了N 次),If-Modified-Since能检查到的粒度是s级的,这种修改无法判断(或者说UNIX记录MTIME只能精确到秒)
解 决办法:如果是这种情况,Apache会自动判断请求时间和修改时间之间的差值,如果小于1s,Apache会认为这个文件在这1秒内可能会再次被修改, 因此生成一个弱Etag(Weak Etag),这个Etag仅仅基于MTime来生成,因此MTime只能精确到s,所以1s内生成的Etag总是一样,这样就避免了使用强Etag造成的 1s内频繁的刷新Cache的情况。(貌似不用Etag,仅仅使用Last-Modified就可以解决,但是这针对的仅仅是修改超级频繁的情况,很多文 件可能同时也使用强Etag验证)。弱Etag以W/开始,比如:W/"2e681a"
问题3、某些服务器不能精确的得到文件的最后修改时间;
解决办法:生成Etag,因为Etag可以综合Inode,MTime和Size,可以避免这个 问题
IIS的ETag 处理机制应该有相似之处。
至此我们较为全面 的介绍了HTTP/1.1协议中关于缓存的处理,以及用户代理,web服务器等相应实现策略。在进行静态文件处理,资源分离,反向代理过程中,很大程度上 要依赖于HTTP协议中缓存命令及各服务器的实现。可以说是我们进行前端优化的一个理论基础。
题外话:
在写这篇文章过程 中,需要查看HTTP/1.1协议,最先看的是英文版,但是阅读速度较慢,因此从网上搜索中文版,最后找到了三份。三份都翻译的很差。最后只能是相互对照 着来看。这么重要的文档,不明白为什么就没有很正式的官方翻译。
术语解释(详见参考文档7):
请求(Request)
一种HTTP 请求消息,参看 第5 章的定义。
应答(Response)
一种HTTP 应答消息,参看 第6 章的定义。
资源(Resource)
一种网络数据对象或 服务,可以用第3.2 节定义的URI 描述。资源可以以多种表现方式
(例如多种语 言,数据格式,大小和解决方案)或其他不同的途径获得。
实体(Entity)
作为请求或应答的有 效负荷而传输的信息.一个实体包含报头形式的维护信息和消息体形式的内容,由第7 节详述.
客户机(Client)
为发送请求建立连接 的程序.
用户代理(User agent)
初始化请求的客户端 程序.常见的如浏览器,编辑器,蜘蛛(网络穿越机器人),或其他的终端用户工具.
服务器(Server)
同意连接以便通过发 回应答为请求提供服务的应用程序.任何给定的程序都有可以既做客户端又做服务器;我们使用这些术语仅指特定连接中程序完成的任务,而不是指通常意义上程序的性能.同样,任何服务器都可以基于每个请求的性质扮演原服务器,代理,网管,或者隧道等诸角色之一。
原服务器(Origin server)
给定的资源驻留或创 建的地方.
保鲜 (Fresh)
如果一个应答的年 龄还没有超过保鲜寿命,它就是保鲜的.
陈旧 (Stale)
一个应答的年龄已 经超过了它的保鲜寿命,就是陈旧的.
参考文档:
1.
缓存友好的网页
http://shiningray.cn/cache-friendly-web-pages.html
2.
Config HTTP Header For Better Client Performance
http://hi.baidu.com/xletian/blog/item/756dcfce4ae17f0692457ed7.html
http://morganchengmo.spaces.live.com/blog/cns!9950CE918939932E!2132.entry
3.
The performance of a Web application may decrease, and the network bandwidth may increase after you add a Web server that is running IIS 5.0 to a Web farm that uses network load balancing
http://support.microsoft.com/kb/922733/en-us
4.
You may experience poor Web performance when you use Internet Explorer 6 to try to access a Web application that is hosted on Internet Information Services 6.0
http://support.microsoft.com/kb/922703/en-us
5.
High Performance Web Sites: Rule 13 – Configure ETags
http://developer.yahoo.net/blog/archives/2007/07/high_performanc_11.html
6.
面向站长和网站管 理员的Web缓存加速指南
http://www.mnot.net/cache_docs/#BROWSER
http://www.chedong.com/tech/cache_docs.html
中文翻译
7.
Http 1.1 Etag 与 Last-Modified
http://www.dbanotes.net/web/http_11_etag_lastmodified.html
8.
Hypertext Transfer Protocol -- HTTP/1.1
http://www.w3.org/Protocols/rfc2616/rfc2616.html
9.
The value in the ETAG field is updated when you modify a metabase property in IIS 6.0
http://support.microsoft.com/kb/900245/en-us
10.
Apache配置文档
http://doc.chinahtml.com/Manual/ApacheManual/mod/core.html
11.
浅谈Etag
http://bbs.chinaunix.net/thread-1186771-1-1.html