缓存的定义
Web缓存是可以自动保存常见文档副本的HTTP设备(包括浏览器?)
缓存的作用
- 减少冗余数据传输
- 缓解带宽瓶颈(很多网络为本地网络客户端提供的带宽比为远程服务器提供的带宽要宽)
- 缓解瞬时拥塞(不会所有的请求都奔着一台服务器去)
- 降低距离时延(就近访问么)
命中、非命中
- 命中率:请求命中缓存的比例
- 字节命中率:请求命中缓存的文档,其文档大小总和,占所有请求大小总和的比例(一些大文档尽管访问少,但对流量贡献大,对于按流量计费的人来说很重要)
客户端如何判断请求是否命中缓存:它能够过Date首部,如果Date的值比当前日期值要早,那么可以认为是缓存的响应。
如何保持副本的新鲜
HTTP通过以下两种机制来实现这样的目的:不要求服务器记住哪些缓存拥有资源副本,同时保持已缓存数据与服务器数据之间的一致。
1. 文档过期(document expiration)—— Cache-Control、Expires
2. 服务器再验证(server revalidation)—— If-Modified-Since(时间)、If-None-Match(结合ETag)
文档过期:相关的header
Expires
HTTP 1.0引入,指定实际的过期时间,而不是秒数。不推荐使用,原因:很多服务器的始终不同步或不正确。使用举例:
Expires: Fri, 05 Jul 2002, 05:00:00 GMT
Cache-Control: max-age
从服务器将资源传送过来时算起,文档处于新鲜的时间(单位为秒)。可通过将其设为0,来请求缓存(服务器)不要缓存资源。举例:
Cache-Control: max-age=0
Cache-Control: no-cache
名字比较有歧义,实际表达的意思是:缓存(服务器)在与原始服务器进行新鲜度再验证前,不能将资源提供给客户端使用。这里包含两个点:
- 标识为
no-cache
的响应实际是可以存储在本地缓冲区的 - 必须每次与原始服务器再校验
举例:
Cache-Control: no-cache
Cache-Control: no-store
带有no-store
的响应,会禁止缓存对资源进行复制。缓存向客户端转发no-store
响应后,会将副本删除。
Cache-Control: must-revalidate
可以使用陈旧(过期)的资源以提高性能。但在没有与原始服务器进行再验证的情况下,不能使用资源的陈旧副本。
与no-cache
的区别:
-
no-cache
:无论资源副本是否过期,都必须与原始服务器进行校验 -
must-revalidate
:资源副本过期前,无需校验;过期后,须校验,如原始服务器上的资源没变化,那么缓存可以提供陈旧的副本。(减少资源传输)
服务器再验证
If-Modified-Since(IMS)
询问服务器,资源在If-Modified-Since
指定的时间之后,是否被修改了,如果
- 没被修改:返回
304 Not Modified
响应报文,同时只会发送需要在源端更新的首部,比如新的过期时间。 - 被修改了:携带新首部的资源会被返回给缓存,包括新的过期时间。
例子:
If-Modified-Since: Sat, 29 Jun 2002, 14:30:00 GMT
If-None-Match
ETag:实体标签(Entity Tag)。ETag再验证的原因:
- 有些文档会被周期性地重写,但实际包含的数据常常是一样的,但修改时间已经发生变化。
- 文档被修改了,但修改并不重要,不需要让所有缓存都失效。
- 某些服务器无法准确判断资源的最后修改时间。
流程与If-Modified-Since
差不多,带上ETag
去服务器查询,如果
- ETag发生变化:返回带有新ETag的资源
- ETag没变化:返回304 Not Modified
例子:
If-None-Match: "v2.6
If-None-Match: "v2.6","v2.7"(告诉服务器,带有这些实体标签的副本缓存上已有了)