在介绍Spring Web对HTTP缓存机制的支持之前,我们有必要了解一下HTTP都有哪些缓存机制,然后再看Spring Web对它们提供了什么样的支持,这样你才能更好地理解和掌握这方面的知识点。
1.HTTP缓存类型
简单来讲,HTTP缓存机制可以分为如下几类 :
- 私有浏览器缓存 (
Private Cache)仅供浏览器用户私有的缓存机制,一般指的就是浏览器缓存机制。这种缓存主要目的是避免发起不必要的请求。
- 共享缓存(
Shared Cache)供多人共享的缓存机制。比如代理服务器缓存,公司网关缓存,
CDN,反向代理缓存,负载均衡器缓存等等。这种缓存主要目的是尽量避免不必要的请求到达服务器。
2.HTTP会缓存哪些资源
通常HTTP缓存只缓存GET方法请求的资源,缓存的主键主要就是"资源URI"。HTTP缓存内容的一般是以下几种情形之一 :
GET+200(OK)成功请求对应的资源,比如HTML,图片,js,css或者其他类型的某个文件;301(Moved Permanently)永久重定向;404(Not Found)资源找不到;206 (Partial Content)只有部分内容;- 不是
GET获取的响应结果,但是也适合缓存的其他情形;
3. 缓存控制指令
对于某种资源是否要被缓存机制缓存,HTTP/1.1中主要是通过请求/响应中的Cache-Control,Expires头部指令来控制的。比如 :
-
不要缓存,总是每次向源服务器请求最新数据
Cache-Control: no-store -
使用缓存副本前,一定要到源服务器进行缓存副本有效性校验
Cache-Control: no-cache -
私有资源,如果你是共享缓存机制,请不要缓存该资源
Cache-Control: private -
公开资源,共享缓存机制或者浏览器私有缓存机制都可以缓存该资源
Cache-Control: public -
设置资源在多少秒之后过期
Cache-Control: max-age=3153600
注意跟头部Expires的区别,头部Expires指定的是资源过期绝对时间点。
如果使用了Cache-Control: max-age=N和Expires,Expires会被忽略。 -
缓存副本过期前,可以使用缓存副本;缓存副本一旦过期,必须去源服务器进行缓存副本有效性校验
Cache-Control: must-revalidate// 和Cache-Control: max-age=0类似
4.缓存保鲜期(Freshness)
我们可以将缓存中的资源叫做"缓存资源副本",而源服务器上真正的该资源叫做"资源正本"。
资源正本在源服务器会发生改变,该改变发生那一刻相应的缓存副本按说就过期了,在过期前的这段时间,我们就可以叫做该资源副本的"保鲜期"(Freshness)。源服务器通过Cache-Control: max-age=N 告知缓存机制一个资源最长存活多长时间的时候,其实是指定了资源副本的"保鲜期",而不是资源正本的"保鲜期",因为资源正本什么时候发生变化,服务器自己都不知道,所以Cache-Control: max-age=N 告知缓存机制的,其实是这样一个语义:“在这个时间之后请向我重新验证该资源副本是否真正过期”。
5.验证缓存资源是否可用(Cache validation)
基于缓存资源副本/正本保鲜期(Freshness)这一概念和上面提到的语义,某个缓存资源副本一旦被认为过期,它会被向服务器重新验证是否真正过期并在真正过期后被重新获取。这个过程中,就涉及到缓存资源副本的验证(Cache validation)。
用户按下浏览器重新加载按钮时(F5)重新验证会被触发。相应头部包含"Cache-control: must-revalidate"重新验证也会被触发。
服务器端在缓存资源副本重新验证请求到达时执行验证过程。该验证过程主要依赖如下头部信息 :
- 强验证器头部 :
ETag/If-None-MatchETag响应头部
语义 : 表示资源是否变化的一个标志字符串;对浏览器来讲是一个黑盒子,浏览器不清楚它的值是什么意思也无从猜测。If-None-Match请求头部
语义 : 是否不能匹配上某个资源。如果缓存资源部分对应资源正本已经变化,则新的资源正本一定会产生一个不同的ETag值,从而使之前的ETag变成无法匹配。
如果对某个资源响应ETag头部被使用,浏览器验证该资源时可以使用此头部,使用ETag的值向服务器询问该资源是否真正过期。
服务器会通过ETag值匹配判断缓存资源副本是否过期。
- 弱验证器头部 :
Last-Modified/If-Modified-SinceLast-Modified响应头部
语义 : 资源最近修改时间。If-Modified-Since请求头部
语义 : 表示资源在某个时间之后是否被修改。
浏览器验证该资源时可以使用此头部,使用Last-Modified的值向服务器询问该资源是否真正过期。
服务器端会使用Last-Modified值和服务器端资源最近一次被修改的时间判断缓存资源副本是否过期。
两种验证算法的区别
- 强验证算法可以理解成是:通过严格文件内容比较,或者内容摘要(指纹)的比较确定资源是否过期。
- 而弱验证算法可以认为是:通过资源修改时间来看,如果缓存资源副本记录的最近修改时间之后资源没有修改过,就可以认为是缓存副本没过期。
- 如果同时使用了强验证机制和弱验证机制,强验证机制会被使用。
有了上述对HTTP缓存机制的总结和梳理,接下来在讲解Spring MVC对HTTP缓存机制的支持时针对性就更强了,也更有助于你理解这些内容。
6.参考资料
关于HTTP缓存机制,网上有很多的资料,如下几篇值得一读 :
- HTTP caching
讲解了不同类型的缓存,可以缓存哪些内容,缓存控制指令,缓存内容新鲜度,缓存内容的验证等。
虽然是英文版,但是结构清晰,图文并茂,不难理解。首推阅读该文章。 - HTTP 缓存
中文版。谷歌开发者网站上的一篇文章。图文并茂,不难理解。(墙外开花墙内香)。
- web性能优化之:no-cache与must-revalidate深入探究
中文。有简介,有场景分析,有比较,图文并茂,值得一读。
- HTTP请求中浏览器的缓存机制
中文。基于资源访问流程直接给出
HTTP请求/响应中缓存有关的头部信息并讲解相关头部字段。列出在页面跳转,浏览器刷新等各种情况下有关HTTP缓存的各种表现及头部信息要点。纯文字版本。 - Caching Tutorial
- HTTP Cache 为什么让人很困惑
相关文章
Spring Web HTTP缓存支持系列1: HTTP缓存机制简介
Spring Web HTTP缓存支持系列2: 支持概述
Spring Web HTTP缓存支持系列3: 对 Cache-Control头部的支持
Spring Web HTTP缓存支持系列4: WebRequest#checkNotModified支持验证器机制
HTTP缓存机制解析

972

被折叠的 条评论
为什么被折叠?



