HTTP静态资源缓存

概述

为了减少服务器带宽的需求,我们要减少客户端与服务器端交互的数据量。解决方法如下:
1. 缓存很少变化的静态资源,比如JS,CSS和图片。
2. 对网络交互的数据进行压缩,比如对JS,CSS,HTML,图片等。
3. 减少客户端与服务器端的交互次数,我们可以合并所有的JS文件,合并所有的CSS文件。

本文主要讨论静态资源的缓存,其余部分请参考其他文章。

缓存位于服务器之间和客户端之间,根据请求保存输出内容的副本,如html页面,图片,文件,当下一个请求来到时,如果相同的URL,直接使用副本响应访问请求,而不向源服务器再次发送请求。

缓存的类型
1. 浏览器缓存
浏览器都有关于缓存的设置(参考:http://www.cnblogs.com/ivanfu/archive/2012/04/26/2471103.html),通过在电脑硬盘存储已经看过的网站的副本。

2. 代理服务器缓存
Web代理服务器使用同样的缓存原理,代理服务器群为成百上千用户服务使用同样的机制;代理服务器缓存是共享缓存,为大量用户使用,因此在减少相应时间和带宽使用方面很有效,同一个副本会被重用多次。

3. 网关缓存
也称为反向代理缓存或间接代理缓存,网关缓存也是一个中间服务器,和内网管理员部署缓存用于节省带宽不同,网关缓存一般是网站管理员自己部署,让他们的网站更容易扩展并获得更好的性能。请求有几种方法被路由到网关缓存服务器上,其中典型的是让用一台或多台负载均衡服务器从客户端看上去是源服务器。网络内容发布商 (Content delivery networks CDNs)分布网关缓存到互联网上,并出售缓存服务给需要的网站。

缓存如何工作
1. 如果响应头信息:告诉缓存器不要保留缓存,缓存器就不会缓存相应内容。
2. 如果请求信息是需要认证或者安全加密的,相应内容默认不会被缓存。
3. 如果在回应中不存在校验器(ETag或者Last-Modified头信息),缓存服务器会认为缺乏直接的更新度信息,内容将会被认为不可缓存。
4. 一个缓存的副本如果含有以下信息,内容将会被认为是足够新的

  • 含有完整的过期时间和寿命控制头信息,并且内容仍在保鲜期内。
  • 浏览器已经使用过缓存副本,并且在一个会话中已经检查过内容的新鲜度。
  • 缓存代理服务器近期内已经使用过缓存副本,并且内容的最后更新时间在上次使用期之前。

5. 如果缓存的副本已经太旧了,缓存服务器将向源服务器发出请求校验请求,用于确定是否可以继续使用当前拷贝继续服务。

五种常用于控制客户端缓存的头标
1. Last-Modified 最后修改时间
这 个头标是一个响应头标,表示客户端(通常指浏览器)所请求资源在服务器端的最后修改时间,通常情况下客户端在接受这个头标后,在以后对这个资源的请求会附 带一个’If-Modified-Since’请求头标,而这个头标是想告诉服务器上次客户端所请求资源的最后修改时间,对于一些图像,css,js等静 态文件资源,配置好了的apache服务器会理解这些If-Modified-Since请求头标,将头标里的时间和文件的最后修改时间进行比较并作出响 应,如果二者相等则发送一个304 Not Modfied来告诉客户端所请求资源并未修改让客户端放心使用缓存中的资源,否则的话会重新发送一个新的资源和新的Last-Modified的头标。 但是对于一个动态的PHP脚本,我们即使在脚本加入了header(‘Last Modified: ‘.$time)来发送一个Last Modified响应头标,当客户端附带’If-Modified-Since’在次请求时apache服务器不会进行处理,这需要我们自己 用$_SERVER['HTTP_IF_MODIFIED_SINCE']来获取’If-Modified-Since’的值自己来进行判断处理。

2. ETag(Entity Tag) 实体标签
和Last-Modified类似,也是WEB服务器和客户端用于确认缓存组件的有效性的一种机制,apache 1.3和2.0的ETag格式是inode-size-timestamp,因此当资源被修改,其ETag也发生改变,ETag相对Last- Modified更精确,Last-Modified只能精确的s级别,但是ETag在多服务器可能造成混乱,所以用还是不用还得看实际情况,其相对应的 后续请求头标为If-None-Match。

3. Expires 过期时间
这个属性告诉缓存器相关副本在多长时间内是新鲜的。过了这个时间,缓存器就会向源服务器发送请求,检查文档是否被修改。几乎所有的缓存服务器都支持Expires属性。可以设计一个绝对时间间隔:基于客户最后查看副本的时间(最后访问时间)或者根据服务器上文档最后被修改的时间。Expires头信息对于设置静态图片缓存特别有用,这些图片修改很少,可以给它们设置一个特别长的过期时间,这会使网站对用户变得相应非常快。

4. Pragma 编译指示
HTTP头信息中Pragma: no-cache 并不一定会让内容无法被缓存,HTTP的规范中,响应型头信息没有任何关于Pragma属性的说明,而讨论了的是请求型头信息 Pragma属性,集中缓存服务器大部分不会用这个参数。

5. Cache-Control 缓存控制
让网站的发布者控制他们的内容,并定位过期时间的限制。比如:Cache-Control: max-age=3600, public,可选项如下:

  • max-age =[秒] 执行缓存的最长时间,[秒]是一个数字,单位是秒:从请求时间开始到过期时间之间的秒数。
  • s-maxage =[秒] 类似于max-age属性,除了他应用于共享(如:代理服务器)缓存
  • public 标记认证内容也可以被缓存,一般来说: 经过HTTP认证才能访问的内容,输出是自动不可以缓存的;
  • no-cache 强制每次请求直接发送给源服务器,而不经过本地缓存版本的校验。这对于需要确认认证应用很有用(可以和public结合使用),或者严格要求使用最新数据的应用(不惜牺牲使用缓存的所有好处);
  • no-store 强制缓存在任何情况下都不要保留任何副本
  • must-revalidate 告诉缓存必须遵循所有你给予副本的新鲜度的,HTTP允许缓存在某些特定情况下返回过期数据,指定了这个属性,高速缓存,希望严格的遵循你的规则。
  • proxy-revalidate 和 must-revalidate类似,除了他只对缓存代理服务器起作用

如何写利于缓存的代码
1. 保持URL稳定,这是缓存的金科玉律,如果在不同的页面上,给不同用户或者从不同的站点上提供相同的内容,应该使用相同的URL,这使网站缓存友好简单,最高效。
2. 尽量避免使用POST,POST模式的返回内容不会被大部分缓存服务器保存,如果你发送内容通过URL和查询(通过GET模式)的内容可以缓存下来供以后使用。
3. 生成并返回Content-Length头信息。这个属性让你的脚本在可持续链接模式时,客户端可以通过一个TCP/IP链接同时请求多个副本,而不是为每次请求单独建立链接,这样你的网站相应会快很多。
4. 对于定期更新的内容设置一个缓存服务器可识别的max-age属性或过期时间。对于不经常改变的图片/页面启用缓存 ,并使用Cache-Control: max-age属性设置一个较长的过期时间。

本文参考:http://www.phphubei.com/article-10586-1.html

posted @ 2012-04-27 15:33  先行而后三思  阅读(3877)  评论(0编辑  收藏  举报