码迷,mamicode.com
首页 > Web开发 > 详细

http 缓存

时间:2015-08-12 16:50:42      阅读:163      评论:0      收藏:0      [点我收藏+]

标签:http

缓存命中和未命中

可以用已有的副本为某些到达缓存的请求提供服务,这被称为缓存命中(cache hit),其他一些到达缓存的请求可能会由于没有副本可用,而被转发给原始服务器,这被称为缓存未命中(cache miss)。

再验证
原始服务器的内容可能发生变化,缓存要是不是对其进行检测,看看他们保存副本是否仍是服务器上的最新的副本。这些“新鲜度检测”被称为HTTP再验证(revalidation)。为了有效的进行再验证,HTTP定义了一些特殊的请求,不用从服务器上获取整个对象,就可以快速的检测出内容是否是最新的。
缓存对缓存的副本进行再验证时,会向原始服务器发送一个小的再验证请求,如果内容没有变化,服务器会以一个小的304 Not Modified进行响应。
技术分享
技术分享
HTTP为我们提供了几个用来对已缓存对象进行再验证的工具,单最常见的就是If-Modified-Since首部。将这个首部添加到GET请求中去,就可以告诉服务器,只有在缓存了对象的副本之后,由对其进行了修改的情况下才发送此对象。

再验证命中:
技术分享
技术分享
技术分享
再验证未命中
技术分享
技术分享
客户端有一种方法可以判断响应是否来自缓存,就是使用Date首部。将响应中Date首部的值与当前时间进行比较,如果响应中的日期比较早,客户端通常就可以认为这是一条缓存的响应。客户端也可以通过Age首部来检测缓存的响应,通过这个首部可以分辨出这条响应的试用期。

缓存的处理步骤:
  1. 接收----缓存从网络中读取抵达的请求报文;
  2. 解析----缓存对报文进行解析,提取出URL和各种首部;
  3. 查询----缓存查看是否有本地副本可用,如果没有,就获取一份副本(并将其保存在本地);
  4. 新鲜度检测----缓存查看本地的副本是否足够新鲜,如果不是,就询问服务器是否有任何更新(HTTP通过缓存将服务器文档的副本保存一段时间。在这段时间内里,都认为文档时“新鲜的”,缓存可以在不联系服务器的情况下,直接提供文档。但是一旦缓存停留的时间太长,超过了文档的新鲜度限制(freshness limit),就认为对象“过时”了,在提供该文档之前,缓存要再次与服务器进行确认,以查看文档是否发生了变化);
  5. 创建响应----缓存会用新的首部和已缓存的主体来构建一条响应报文(我们希望缓存的响应看起来就像来自原始服务器一样,缓存将已缓存的服务器响应首部作为响应首部的起点,然后缓存对这些基础首部进行了修改和扩充例如针对HTTP/0.9的请求返回HTTP/1.1,还有向首部中插入新鲜度信息(Cache-Control、Age以及Expires首部));
  6. 发送----缓存通过网络将响应发回给客户端;
  7. 日志----缓存可选的创建一个日志文件条目来描述这个事物;

注意:
  1. 已缓存的对象包含了服务器的响应主体和原始服务器的响应首部新鲜度检测的时候只会返回原始服务器的响应首部,而没有响应主体)。
  2. 第五步中缓存不应该调整Date首部,Date首部表示的是原始服务器最初产生的对象的日期。

技术分享
保持新鲜度
HTTP保持新鲜度机制为文档过期(document expiration)和服务器再验证(server revalidation)。


文档过期
通过特殊的HTTP Cache-Control首部和Expires首部,HTTP让原始服务器向每个文档附加了一个“过期日期”。这些首部说明了在多长时间内可以将这些内容是为新鲜的。
技术分享
技术分享
HTTP/1.0+ Expires和HTTP/1.1 Cache-Control:max-age=seconds用来执行文档的过期时间,如果同时有两个首部用来指定过期时间,以 Cache-Control首部指定的值为准。

注意:由于 Cache-Control使用的是相对时间来指定的过期时间,所以一般使用Cache-Control来指定过期时间。

服务器再验证:
  1. 如果再验证显示内容发生了变化,缓存会获取一份新的文档副本,并将其存储在就文档的位置上,然后将文档发送给客户端;
  2. 如果再验证显示内容没有发生变化,缓存只需要获取新的首部。包括一个新的过期时间,并对缓存中的首部进行更新就行了


用条件方法进行再验证
HTTP的条件方法可以高效的实现再验证。HTTP允许缓存向原始服务器发送一个“条件GET”,请求服务器只有在文档与缓存中现有的副本不同时,才回送对象主体。通过这种方式,将新鲜度检测和对象获取结合成了单个条件GET。

If-Modified-Since:<date>
如果从指定日期之后文档被修改过了,就执行请求的方法。可以与服务器响应首部Last-Modified配合使用(
If-Modified-Since : <Last-Modified date>   //存放的是最后的修改时间,如果在最后修改时间之后修改了文档,向原始服务器重新取得副本),只有在内容被修改后与已缓存版本有所不同的时候才去获取内容。

如果指定日志之后,文档被修改了,If-Modified-Since条件为真,通常GET就会成功执行。携带新首部的新文档会被返回给缓存,新首部除了其他信息之外,还包括一个新的过期日期。

如果指定日志之后,文档没有被修改,If-Modified-Since条件为假,会返回一个304 Not Modified响应报文,为了提高效率,不会返回文档的主体,只返回那些需要在源端更新的首部,304 Not Modified首部中会柏涵一个新的过期日期。

If-None-Match: <tags>(实体标签验证)
在有些情况下,If-Modified-Since无法使用时(比如实时监控信息,使用If-Modified-Since可能不适用等),使用If-None-Match进行验证。
技术分享
技术分享
If-None-Match和服务器返回的ETag匹配时,说明该缓存是有效的,否则说明缓存无效,从原始服务器取得新的副本。

当某些情况下,对小的修改不希望缓存失效时,使用弱验证器进行验证。
ETag : W/"v.2.6"



控制缓存的能力
优先级递减的顺序如下:
  1. Cache-Control:no-store(禁止缓存服务器复制文档副本,缓存服务器给客户端返回响应之后,删除文档对象)
  2. Cache-Control:no-cache(响应可以存放在缓存中,但是必须进行有效性验证)
  3. Cache-Control:must-devalidate
  4. Cache-Control:max-age=seconds(定义了从date开始的多长时间内响应被认为是新鲜的,不用进行有效性验证,为0表示必须验证)
  5. 附加一个Expires日期首部到响应中去(执行缓存响应的过期时间)
  6. 不附加过期日期,然缓存确定自己的过期日期

版权声明:本文为博主原创文章,未经博主允许不得转载。

http 缓存

标签:http

原文地址:http://blog.csdn.net/td901105td/article/details/47446285

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!