对于您的站点的访问者来讲,智能化的内容缓存是提升用户体验最有效的方式之一。缓存,或者对以前的请求的临时存储,是HTTP协议实现中最核心的内容分发策略之一。分发路径中的组件都可以缓存内容来加速后续的请求,这受控于对该内容所声明的缓存策略。后端
在这份指南中,咱们将讨论一些Web内容缓存的基本概念。这主要包括如何选择缓存策略以保证互联网范围内的缓存可以正确的处理您的内容。咱们将谈一谈缓存带来的好处、反作用以及不一样的策略能带来的性能和灵活性的最大结合。浏览器
缓存(caching)是一个描述存储可重用资源以便加快后续请求的行为的术语。有许多不一样类型的缓存,每种都有其自身的特色,应用程序缓存和内存缓存因为其对特定回复的加速,都很经常使用。缓存
这份指南的主要讲述的Web缓存是一种不一样类型的缓存。Web缓存是HTTP协议的一个核心特性,它能最小化网络流量,而且提高用户所感知的整个系统响应速度。内容从服务器到浏览器的传输过程当中,每一个层面均可以找到缓存的身影。服务器
Web缓存根据特定的规则缓存相应HTTP请求的响应。对于缓存内容的后续请求即可以直接由缓存知足而不是从新发送请求到Web服务器。cookie
有效的缓存技术不只能够帮助用户,还能够帮助内容的提供者。缓存对内容分发带来的好处有:网络
在面对缓存时,您可能对一些常常遇到的术语可能不太熟悉。一些常见的术语以下:架构
还有许多其余的缓存术语,不过上面的这些应该能帮助您开始。并发
某些特定的内容比其余内容更容易被缓存。对大多数站点来讲,一些适合缓存的内容以下:工具
这些文件更倾向于不常常改变,因此长时间的对它们进行缓存能得到好处。性能
一些项目在缓存中必须加以注意:
一些内容历来不该该被缓存:
除上面的通用规则外,一般您须要指定一些规则以便于更好地缓存不一样种类的内容。例如,若是登陆的用户都看到的是一样的网站视图,就应该在任何地方缓存这个页面。若是登陆的用户会在一段时间内看到站点中用户特定的视图,您应该让用户的浏览器缓存该数据而不该让任何中介节点缓存该视图。
Web内容会在整个分发路径中的许多不一样的位置被缓存:
上面的这些位置一般均可以根据它们自身的缓存策略和内容源的缓存策略缓存一些相应的内容。
缓存策略依赖于两个不一样的因素。所缓存的实体自己须要决定是否应该缓存可接受的内容。它能够只缓存部分能够缓存的内容,但不能缓存超过限制的内容。
缓存行为主要由缓存策略决定,而缓存策略由内容拥有者设置。这些策略主要经过特定的HTTP头部来清晰地表达。
通过几个不一样HTTP协议的变化,出现了一些不一样的针对缓存方面的头部,它们的复杂度各不相同。下面列出了那些你也许应该注意的:
Expires
**:尽管使用范围至关有限,但Expires
头部是很是简洁明了的。一般它设置一个将来的时间,内容会在此时间过时。这时,任何对一样内容的请求都应该回到原始服务器处。这个头部或许仅仅最适合回退模式(fall back)。Cache-Control
**:这是Expires
的一个更加现代化的替换物。它已被很好的支持,且拥有更加灵活的实现。在大多数案例中,它比Expires
更好,但同时设置二者的值也无妨。稍后咱们将讨论您能够设置的Cache-Control
的详细选项。ETag
**:ETag
用于缓存验证。源服务器能够在首次服务一个内容时为该内容提供一个独特的ETag
。当一个缓存须要验证这个内容是否即将过时,他会将相应的ETag
发送回服务器。源服务器或者告诉缓存内容是一致的,或者发送更新后的内容(带着新的ETag
)。Last-Modified
:这个头部指明了相应的内容最后一次被修改的时间。它可能会做为保证内容新鲜度的验证策略的一部分被使用。Content-Length
**:尽管并无在缓存中明确涉及,Content-Length
头部在设置缓存策略时很重要。某些软件若是不提早获知内容的大小以留出足够空间,则会拒绝缓存该内容。Vary
**:缓存系统一般使用请求的主机和路径做为存储该资源的键。当判断一个请求是不是请求一样内容时,Vary
头部能够被用来提醒缓存系统须要注意另外一个附加头部。它一般被用来告诉缓存系统一样注意Accept-Encoding
头部,以便缓存系统可以区分压缩和未压缩的内容。Vary
头部提供给您存储同一个内容的不一样版本的能力,代价是下降了缓存的容量。
在使用Accept-Encoding
时,设置Vary
头部容许明确区分压缩和未压缩的内容。这在服务某些不能处理压缩数据的浏览器时很重要,它能够保证基本的可用性。Vary
的一个典型的值是Accept-Encoding
,它只有两到三个可选的值。
一开始看上去User-Agent
这样的头部能够用于区分移动浏览器和桌面浏览器,以便您的站点提供差别化的服务。但User-Agent
字符串是非标准的,结果将会形成在中间缓存中保存同一内容的许多不一样版本的缓存,这会致使缓存命中率的下降。Vary
头部应该谨慎使用,尤为是您不具有在您控制的中间缓存中使请求标准化的能力(也许能够,好比您能够控制CDN的话)。
上面咱们提到了Cache-Control
头部如何被用与现代缓存策略标准。可以经过这个头部设定许多不一样的缓存指令,多个不一样的指令经过逗号分隔。
一些您可使用的指示内容缓存策略的Cache-Control
的选项以下:
no-cache
:这个指令指示全部缓存的内容在新的请求到达时必须先从新验证,再发送给客户端。这条指令实际将内容马上标记为过时的,但容许经过验证手段从新验证以免从新下载整个内容。no-store
:这条指令指示缓存的内容不能以任何方式被缓存。它适合在回复敏感信息时设置。public
:它将内容标记为公有的,这意味着它能被浏览器和其余任何中间节点缓存。一般,对于使用了HTTP验证的请求,其回复被默认标记为private
。public
标记将会覆盖这个设置。private
:它将内容标记为私有的。私有数据能够被用户的浏览器缓存,但不能被任何中间节点缓存。它一般用于用户相关的数据。max-age
:这个设置指示了缓存内容的最大生存期,它在最大生存期后必须在源服务器处被验证或被从新下载。在现代浏览器中这个选项大致上取代了Expires
头部,浏览器也将其做为决定内容的新鲜度的基础。这个选项的值以秒为单位表示,最大能够表示一年的新鲜期(31536000秒)。s-maxage
:这个选项很是相似于max-age
,它指明了内容可以被缓存的时间。区别是这个选项只在中间节点的缓存中有效。结合这两个选项能够构建更加灵活的缓存策略。must-revalidate
:它指明了由max-age
、s-maxage
或Expires
头部指明的新鲜度信息必须被严格的遵照。它避免了缓存的数据在网络中断等相似的场景中被使用。proxy-revalidate
:它和上面的选项有着同样的做用,但只应用于中间的代理节点。在这种状况下,用户的浏览器能够在网络中断时使用过时内容,但中间缓存内容不能用于此目的。no-transform
:这个选项告诉缓存在任何状况下都不能由于性能的缘由修改接收到的内容。这意味着,缓存不容许压缩接收到的内容(没有从原始服务器处接收过压缩版本的该内容)并发送。这些选项可以以不一样的方式结合以得到不一样的缓存行为。一些互斥的值以下:
no-cache
,no-store
以及由其余前面未提到的选项指明的经常使用的缓存行为public
和private
若是no-store
和no-cache
都被设置,那么no-store
会取代no-cache
。对于非受权的请求的回复,public
是隐含的设置。对于受权的请求的回复,private
选项是隐含的。他们能够经过在Cache-Control
头部中指明相应的相反的选项以覆盖。
在理想状况下,任何内容均可以被尽量缓存,而您的服务器只须要偶尔的提供一些验证内容便可。但这在现实中不多发生,所以您应该尝试设置一些明智的缓存策略,以在长期缓存和站点改变的需求间达到平衡。
在许多状况中,因为内容被产生的方式(如根据每一个用户动态的产生)或者内容的特性(例如银行的敏感数据),这些内容不该该被缓存。另外一些许多管理员在设置缓存时可能面对的问题是外部缓存的数据未过时,但新版本的数据已经产生。
这些都是常常遇到的问题,它们会影响缓存的性能和您提供的数据的准确性。然而,咱们能够经过开发提早预见这些问题的缓存策略来缓解这些问题。
尽管您的实际状况会指导您选择的缓存策略,可是下面的建议能帮助您得到一些合理的决定。
在您担忧使用哪个特定的头部以前,有一些特定的步骤能够帮助您提升您的缓存命中率。一些建议以下:
对于不一样的文件正确地选择不一样的头部这件事,下面的内容能够做为通常性的参考:
Cache-Control
头部中使用no-cache
或no-store
选项。ETag
和Last-Modified
头部将容许缓存向原始服务器验证内容,并在内容未修改时刷新该内容新鲜度以减小负载。关键之处便在于达到平衡,一方面能够尽可能的进行缓存,另外一方面为将来保留当改变发生时从而改变整个内容的机会。您的站点应该同时具备:
这样作的目的即是将内容尽量的移动到第一个分类(尽可能缓存)中的同时,维持能够接受的缓存命中率。