HTTP缓存
web 缓存简介
web 缓存是可以自动保存常见文档副本的 HTTP 设备,当 web 请求抵达缓存时,如果本地有已缓存的副本,就可以从本地存储设备而不是原始服务器中提取这个文档
使用缓存有很多优点
缓存减少了冗余的数据传输,节省网络费用
有很多客户端访问同一个服务器时,服务器会多次传输同一份文档,相同的字节会不断地在网络中传输,这些冗余的数据传输极大地消耗了网络带宽,降低传输速度,加重了 web 服务器的负载
使用缓存之后,在缓存中保留第一条服务器响应的副本,后续的请求由缓存副本来应对
缓存缓解了网络瓶颈问题。不需要更多的带宽就能够更快的加载页面
缓存降低了对原始服务器的要求。服务器可以更快地响应,避免过载的出现
在破坏瞬间拥塞(flash crowds)的时候十分重要
缓存降低了距离时延,因为从较远的地方加载页面会更慢一些
每台网络路由器都会增加因特网流量的时延,光速本身也会造成时延。将缓存放在客户端附近可以有效的减少距离时延
缓存的类型通常有两种:
私有缓存(private cache)—— 通常存放在 web 浏览器中
共有缓存(public cache)—— 缓存代理服务器(cache proxy server),也叫代理缓存
缓存命中与未命中
缓存命中(cache hit)—— 可以用已有的副本为某些达到缓存的请求提供服务
缓存未命中(cache miss)—— 到达缓存的请求可能会由于没有副本可用,而被转发给原始服务器
实际中,服务器上的内容常常发生变化,缓存要经常对其进行新鲜度检测,以判断保存的副本是否仍是服务器上的最新的副本
这种新鲜度检测也被称为 HTTP 再验证(revalidation)
理论上,缓存可以在任意时刻以任意频率对副本进行验证,但通常由于网络的限制,大部分缓存只有在客户端发起请求,并且副本“旧”得足以需要检测的时候才会对副本进行验证
缓存对副本进行再验证时,通常会使用 If-Modified-Since 首部向原始服务器发送一个验证请求,服务器上的文件会有三种情况
内容未修改 —— 再验证命中(revalidate hit)/ 缓慢命中(slow hit)
如果服务器上相应的对象未被修改,服务器会向客户端发送 304 Not Modified 响应,此时缓存知道副本仍有效,会将副本标记为暂时新鲜的,并将副本提供给客户端
这种情况下比单纯的缓存命中要慢,但并未从服务器中获取对象数据,故比缓存未命中要快
内容已修改但未删除 —— 再验证未命中
如果服务器对象与缓存的不同,服务器向客户端发送一条普通的、带完整内容的 200 OK 响应
内容被删除
如果服务器中的数据对象被删除,服务器返回 404 Not Found 响应,缓存也会将其副本删除
缓存的处理步骤
对一条 HTTP GET 报文的基本缓存处理过程包括 7 个步骤
接收
缓存从网络中读取抵达的请求报文
解析
缓存对报文进行解析,提取出 URL 和各种首部
查询
缓存查看是否有本地副本可用,如果没有,就获取一份副本并将其保存在本地
新鲜度检测
缓存查看已缓存的副本是否足够新鲜,如果不是,就询问服务器是否有任何更新
创建响应
缓存会用新的首部和已缓存的主体来构建一条响应报文
发送
缓存通过网络将响应发回给客户端
日志
缓存可选地创建一个日志文件条目来描述这个事务
保持副本的新鲜
日常生活中产生的、存放在服务器中的文档可能会经常变化,而客户端需要的往往是最新的数据。因此,已缓存的数据要与服务器数据保持一致
HTTP 可以在不要求服务器记住哪些缓存拥有其文档副本的情况下,保持已缓存数据与服务器数据之间的充分一致,这些机制称为文档过期(document expiration)和服务器再验证(server revalidation)
文档过期
服务器用 HTTP/1.0+ 的 Expires 首部或 HTTP/1.1 的 Cache-Control: max-age 响应首部来指定过期日期,同时还会带有响应主体
Expires
指定一个绝对的过期日期,如果过期日期已经过了,就说明文档已经不新鲜了
1
Expires: Mon, 30 Sep 2019, 10:00:00 GMT
Cache-Control: max-age
max-age
定义了文档的最大使用期 —— 从第一次生成文档到文档不再新鲜、无法使用为止最大的合法生存时间(以秒为单位)1
Cache-Control: max-age=600