【HTTP】缓存

随着用户访问量越来越大,缓存变得越来越重要。HTTP文件缓存可以减少冗余数据的传输;缓解网络瓶颈;降低对原始服务器的请求;以及降低距离延迟。

命中和未命中

有了缓存,就可以保留第一条服务器响应的副本,后继请求就可以有缓存的副本来应对了。可以用已有的副本为某些达到缓存的请求提供服务,这些被称为缓存命中(cache hit)。HTTP没有为用户提供一种手段来区分响应是否缓存命中的,还是访问原始服务器得到的。在客户端使用Date首部,将响应中Date首部的值与当前时间进行比较,如果响应中的日期值比较早,客户端通常就可以认为是一条缓存的响应。现代浏览器通常会使用200 OK (from disk cache)进行标识来自缓存

再验证

原始服务器的内容可能会发生变化,缓存要不时的对其进行检测,看看它们保存的副本是否仍是服务器上最新的副本,这些“新鲜度检测”被称为HTTP再验证(revalidation)。

文档过期

通过特殊的HTTP Cache-Control:max-age首部(HTTP/1.1)和Expires首部(HTTP/1.0+),HTTP让原始服务器向每个文档附件一个“过期日期”。在文档过期之前,缓存可以以任意频率使用这些副本,而无需与服务器联系(不会发起任何请求)。

首部

描述

Cache-Control:max-age

max-age值定义了文档的最大使用期—从第一次生成文档到文档不再新鲜、无法使用为止(单位:秒) Cache-Control:max-age=3600

Expires

指定一个绝对的过期日期 Expires:Fri, 30 Jun 2017 11:40:21 GMT

用条件方法进行再验证

HTTP的条件方法可以高效地实现再验证。HTTP允许缓存向原始服务器发送一个“条件Get请求”,请求服务器只有在文档与缓存中现有的副本不同时,才回送对象主体;否则值返回304 Not Modified,不携带主体。

首部

描述

If-Modified-Since:<date>

如果从指定日期之后文档被修改过了,就执行请求的方法。可以与Last-Modified服务器响应首部配合使用,只有在内容被修改后与已缓存版本有所不同时才去获取内容。

If-None-match:<tags>

服务器可以为文档提供特殊的标签ETag,而不是将其与最近日期相匹配,这些标签就像序列号一样。如果已缓存标签与服务器文档中的标签有所不同,就会执行请求的方法。

如果服务器发送了一个实体标签,HTTP/1.1客户端就必须使用实体标签验证器。如果服务器只回送了一个Last-Modified值,客户端就可以使用If-Modified-Since验证。如果都提供了,HTTP/1.0和HTTP/1.1缓存都可以正确响应。

缓存的处理步骤

(1)接收—缓存从网络中读取抵达的请求报文; (2)解析—缓存对报文进行解析,提取出URL和各种首部; (3)查询—缓存查看是否已有本地副本可用,如果没有,就获取一份副本(并将其保存在本地); (4)新鲜度检测—缓存查看已缓存副本是否足够新鲜,如果不是,就询问服务器是否有任何更新条件Get请求; (5)创建响应—缓存会用新的首部和已缓存的主体来构建一条响应报文; (6)发送—缓存通过网络将响应发回给客户端; (7)日志—缓存可选地创建一个日志文件条目来描述这个事物。

  1. Cache-Control:相对时间(秒为单位)(或者,Expires:绝对时间)如果未过期,直接读取浏览器缓存文件,不发生任何HTTP请求。
  2. 在浏览器端判断上次返回头中是否包含Etag信息,有则连同If-None-Match一起向服务器端发送条件Get请求,304说明未做过修改,如果是200需要进入下一步;
  3. 在浏览器端判断上次返回头中是否包含Last-Modify信息,有则连同If-Modified-Since一起向服务器端发送条件Get请求,内容失效返回200,否则304;
  4. 如果Etag和Last-Modify都不存在,直接向服务器请求。

注意:如果返回304,不会有内容,节省请求大小!

控制缓存的能力

服务器可以通过HTTP定义的几种方式来指定在文档过期之前可以将其缓存多长时间。按照优先级递减的顺序:

  • 附件一个Cache-Control: no-store首部到响应中去;
  • 附件一个Cache-Control: no-cache首部到响应中去;
  • 附件一个Cache-Control: must-revalidate首部到响应中去;
  • 附件一个Cache-Control: max-age首部到响应中去;
  • 附加一个Expires日期首部到响应中去;
  • 不附加过期信息,让缓存确定自己的过期日期。

注意:标识为no-store的响应会禁止缓存对响应进行复制。缓存通常会像非缓存代理服务器一样,向客户端转发一条no-store响应,热后删除对象;标识为no-cache的响应实际上是可以存储在本地缓存区中的,只是在与原始服务器进行新鲜度再验证之前,缓存不能将其提供给客户端使用。

客户端的新鲜度限制

Web浏览器都有Refresh(刷新)或Reload(重载)按钮,可以强制对浏览器或代理缓存中可能过期的内容进行刷新。Refresh按钮会发布一个附加了Cache-Control请求首部的Get请求,这个请求会强制进行再验证,或者无条件地从服务器获取文档。

Safari/Firefox浏览器下通过Cache-Control:max-age=0进行控制;Chrome浏览器勾选Disable cache下通过Cache-Control:no-cache Pragma:no-cache

注意:HTML2.0定义了<META HTTP-EQUIV="Cache-control" CONTENT="no-cache">来标记非缓存,其并不是控制文档缓存特性的最好方法。

缓存和广告

广告通常是向用户显示一次广告内容,内容提供商就会得到相应的收益。缓存—它们会向原始服务器隐藏实际的访问次数。现在广告商会使用各种类型的“缓存清除”技术来确保缓存不会窃取他们的命中流量。常用解决方案:每次访问都与原始服务器进行再验证(携带no-cache或每次访问重写广告URL)。这样,每次访问都会将命中推向原始服务器,但通常不会传送任何主题数据,不会降低失误处理速度。

缓存层次结构

其基本思想是在靠近客户端的地方使用小型廉价缓存,而更高层次中,则逐步采用更大、功能更强的缓存来装载多用户共享的文档。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券