4/10/2009

前端页面优化-HTTP/1.1协议中缓存处理和web服务器实现(二)

标签响应报头值,一个实体标签,提供了一个"模糊"缓存验证器.这将允许在不便存 储修改信息的情况下进行可靠的确认,包括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

也可以修改

下载地址:


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

没有评论: