Web Caching Basics: Terminology, HTTP Headers, and Caching Strategies(译)
原文地址:Web Caching Basics: Terminology, HTTP Headers, and Caching Strategies
介绍
智能的内容缓存是改善网站访问体验的最有效方法之一。 缓存或临时存储来自先前请求的内容,是HTTP协议中实现的核心内容交付策略的一部分。 整个传递路径中的组件都可以缓存所有项目,以加快后续请求的速度,具体取决于为内容声明的缓存策略。
在本指南中,我们将讨论Web内容缓存的一些基本概念。 这将主要涵盖如何选择缓存策略以确保整个Internet的缓存都能正确处理您的内容。 我们将讨论缓存所带来的好处,需要注意的副作用以及为保障性能和灵活性的最佳组合而采用的不同策略。
什么是缓存?
缓存是用于存储可复用响应来使后续的请求更快的术语。 有许多不同类型的缓存可用,每种缓存都有自己的特征。 应用程序缓存和内存缓存均因其加速某些响应的能力而广受欢迎。
Web缓存是本指南的重点,它是另一种类型的缓存。 Web缓存是HTTP协议的核心设计功能,旨在最大程度地减少网络流量,同时改善整个系统的感知响应能力。 从原始服务器到浏览器的内容旅程的每个级别都可以找到缓存。
Web缓存通过根据某些规则缓存请求的HTTP响应来工作。 然后,可以从更靠近用户的缓存中满足对缓存内容的后续请求,而不是将请求一直发送回Web服务器。
好处
有效的缓存有助于内容使用者和内容提供者。 缓存为内容交付带来的一些好处是:
-
改进的响应速度:缓存使内容检索速度更快,因为不需要整个网络往返。 保持接近用户的缓存(例如浏览器缓存)可以使此检索几乎是瞬时的。
-
在同一硬件上提高了性能:对于内容的起源服务器,通过最大程度的缓存,可以从同一硬件中压榨出更多性能。 内容所有者可以利用交付路径上功能强大的服务器来首当其冲地加载某些内容。
-
网络中断期间内容的可用性:使用某些策略,即使原始服务器可能在短时间内无法使用内容,也可以使用缓存为终端用户提供内容。
术语
在处理缓存时,可能会遇到一些您可能不熟悉的术语。 以下是一些较常见的:
-
Origin server:原始服务器是内容的原始位置。 如果您是Web服务器管理员,则由您控制。 它负责提供沿请求路由无法从缓存中检索到的任何内容,并负责为所有内容设置缓存策略。
-
Cache hit ratio:缓存的有效性是根据缓存的命中率或命中率来衡量的。 这是能够从缓存中检索的请求与发出的总请求的比率。 高速缓存命中率高意味着可以从高速缓存中检索到较高百分比的内容。 对于大多数管理员来说,这通常是理想的结果。
-
Freshness:新鲜度是一个术语,用于描述高速缓存中的项目是否仍被视为提供给客户端的候选对象。 高速缓存中的内容仅在高速缓存策略指定的刷新时间范围内才会用于响应。
-
Stale content:缓存中的项目将根据缓存策略中的缓存新鲜度设置而过期。 过期的内容是“陈旧的”。 通常,过期的内容不能用于响应客户端请求。 必须重新联系原始服务器以检索新内容,或者至少验证高速缓存的内容仍然准确。
-
Validation:可以验证缓存中的陈旧项目,以刷新其过期时间。 验证涉及与原始服务器进行签入,以查看缓存的内容是否仍代表该项目的最新版本。
-
Invalidation:无效是在其指定的到期日期之前从缓存中删除内容的过程。 如果在原始服务器上更改了该项目,并且缓存中有过期的项目会对客户端造成重大问题,则这是必需的。
还有很多其他缓存术语,但是上面的术语应该可以帮助您入门。
什么可以被缓存?
某些内容比其他内容更易于缓存。 对于大多数网站,一些非常易于缓存的内容是:
- Logo和品牌图片
- 一般非旋转的图片(例如,导航icon)
- 样式表
- 常规Javascript文件
- 可下载的内容
- 媒体文件
这些往往不经常更改,因此它们的缓存可以长时间受益。
对于以下项目,需要小心缓存:
- HTML页面
- 可旋转的图片
- 经常修改的Javascript和CSS
- 请求的内容中带有身份验证Cookie
几乎不应该缓存的一些项目是:
- 与敏感数据相关的资产(银行信息等)
- 用户敏感且经常更改的内容
除了上述一般规则外,还可以指定一些策略,使您可以适当地缓存不同类型的内容。 例如,如果所有通过身份验证的用户都看到您的站点的相同视图,则可以将该视图缓存到任何地方。 如果经过身份验证的用户看到对用户敏感的网站视图(该视图在一段时间内仍然有效),则您可以告诉用户的浏览器进行缓存,但告诉所有中间缓存不要存储该视图。
web内容的缓存位置
内容可以在整个交付链的许多不同位置进行缓存:
-
浏览器缓存:Web浏览器本身维护一个小的缓存。 通常,浏览器会设置一个策略,指示要缓存的最重要项目。 这可能是用户特定的内容,也可能是下载内容昂贵且可能再次被请求的内容。
-
中间缓存代理:客户端和基础结构之间的任何服务器都可以根据需要缓存某些内容。 这些缓存可以由ISP或其他独立方维护。
-
反向缓存:您的服务器基础结构可以为后端服务实现自己的缓存。 这样,可以从联系点为内容提供服务,而不必在每个请求上访问后端服务器。
这些位置中的每个位置都可以并且经常根据其自身的缓存策略和在内容来源设置的策略来缓存项目。
缓存 Headers
缓存策略取决于两个不同的因素。 缓存实体本身可以决定是否缓存可接受的内容。 它可以决定缓存的数量少于允许缓存的数量,但决不能超过。
大部分缓存行为由内容所有者设置的缓存策略确定。 这些策略主要通过使用特定的HTTP headers来阐明。
通过HTTP协议的各种迭代,出现了几种不同的,针对缓存的headers,其复杂程度各不相同。 您可能仍需要注意的内容如下:
-
Expires:Expires header很简单,尽管范围相当有限。 基本上,它设置内容在将来到期的时间。 此时,对相同内容的任何请求都必须返回到原始服务器。 最好仅将此header用作回退。
-
Cache-Control:这是Expires标头的更现代的替代。它得到了很好的支持,并实现了更加灵活的设计。在几乎所有情况下,这都比Expires更可取,但是同时设置这两个值可能不会受到损害。稍后我们将讨论可通过Cache-Control设置的选项的细节。
-
Etag:Etag标头用于缓存验证。当商品最初提供内容时,原产地可以为其提供唯一的Etag。当缓存需要在过期时验证其现有内容时,它可以将其拥有的Etag发回。源将告诉缓存内容相同,或发送更新的内容(带有新的Etag)。
-
Last-Modified:此标头指定该项目的上次修改时间。这可以用作验证策略的一部分,以确保内容新鲜。
-
Content-Length:虽然不专门参与缓存,但是Content-Length标头在定义缓存策略时很重要。如果某些软件事先不知道需要保留空间的内容大小,则将拒绝缓存内容。
-
Vary:缓存通常使用请求的主机和资源路径作为存储缓存项的键。在确定请求是否针对同一项目时,Vary标头可用于告诉缓存注意另一个标头。这也是最常用的方法,也可以通过Accept-Encoding标头告知缓存键,以便缓存知道区分压缩内容和未压缩内容。
关于Vary Header
Vary标头使您能够存储相同内容的不同版本,但要以稀释缓存中的条目为代价。
在Accept-Encoding的情况下,设置Vary标头可以在压缩内容和未压缩内容之间进行严格区分。必须正确地将这些项目提供给无法处理压缩内容的浏览器,并且这是提供基本可用性所必需的。告诉您Accept-Encoding可能是Vary的一个不错的选择的特征是它只有两个或三个可能的值。
乍一看,诸如User-Agent之类的项目似乎是区分移动浏览器和桌面浏览器以服务于您网站的不同版本的好方法。但是,由于User-Agent字符串是非标准的,因此结果可能是中间缓存上相同内容的许多版本,并且缓存命中率非常低。 Vary标头应谨慎使用,尤其是在您无法规范所控制的中间缓存中的请求的情况下(例如,如果您利用内容交付网络,则有可能)。
Cache-Control标志如何影响缓存
上面,我们提到了如何将Cache-Control标头用于现代缓存策略规范。 可以使用此标头设置许多不同的策略指令,多个指令之间用逗号分隔。
可用于指示内容的缓存策略的某些Cache-Control选项包括:
-
no-cache::此指令指定任何缓存的内容在提供给客户端之前必须在每个请求上重新验证。实际上,这会立即将内容标记为陈旧,但允许其使用重新验证技术来避免再次重新下载整个项目。
-
no-store:此指令指示内容不能以任何方式缓存。如果响应代表敏感数据,则进行此设置很合适。
-
public:这将内容标记为公共,这意味着它可以被浏览器和任何中间缓存所缓存。对于使用HTTP身份验证的请求,默认情况下将响应标记为私有。此标题将覆盖该设置。
-
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 and private
如果两个都存在,则no-store选项取代no-cache。 对于未经身份验证的请求的响应,则暗示为public。 对于对已认证请求的响应,暗含了private。 通过在Cache-Control header中包含相反的选项,可以覆盖这些内容。
制定缓存策略
在理想的情况下,所有内容都可以积极地进行缓存,并且仅偶尔与您的服务器联系以验证内容。 不过,这在实践中并不经常发生,因此您应该尝试设置一些理智的缓存策略,以在实现长期缓存和响应不断变化的站点的需求之间取得平衡。
常见问题
在许多情况下,由于内容的生成方式(每个用户动态生成)或内容的性质(例如敏感的银行信息),无法或不应实施缓存。 许多管理员在设置缓存时面临的另一个问题是,即使已发布了新版本,您旧版本的内容仍然泛滥成灾而尚未过期。
这些都是经常遇到的问题,可能会对缓存性能和所提供内容的准确性产生严重影响。 但是,我们可以通过制定可预见这些问题的缓存策略来减轻这些问题。
一般建议
尽管您的情况将决定您使用的缓存策略,但以下建议可以帮助您做出一些合理的决定。
在担心使用的特定header之前,可以采取某些步骤来增加高速缓存命中率。 一些想法是:
-
建立特定的目录,用于存放images,css,和共享内容:将内容放在专用目录中,将使您可以轻松地从网站上的任何页面引用它们。
-
使用相同的URL来引用相同的项:由于缓存密钥不包含主机和请求内容的路径,因此请确保在所有页面上以相同的方式引用内容。 先前的建议使此操作变得容易得多。
-
尽可能使用CSS 精灵图像:图标和导航等项目的CSS图像精灵可减少呈现网站所需的往返次数,并允许您的网站长时间缓存该单个图片。
-
尽可能在本地托管脚本和外部资源:如果您使用javascript脚本和其他外部资源,请在上游没有提供正确的标头的情况下考虑将这些资源托管在您自己的服务器上。 请注意,您将必须知道对上游资源所做的任何更新,以便可以更新本地副本。
-
指纹缓存项:对于静态内容(如CSS和Javascript文件),最好对每个项进行指纹识别。 这意味着向文件名添加一个唯一的标识符(通常是文件的哈希),以便如果修改了资源,则可以请求新的资源名称,从而使请求正确地绕过缓存。 有各种各样的工具可以帮助创建指纹并修改HTML文档中的指纹引用。
在为不同的项目选择正确的header方面,以下内容可以作为一般参考:
-
允许所有缓存存储常规资产:静态内容和非用户特定的内容可以并且应该在传递链的所有点上进行缓存。 这将使中间缓存可以响应多个用户的内容。
-
允许浏览器缓存用户特定的资产:对于每个用户的内容,允许在用户浏览器中进行缓存通常是可接受且有用的。 虽然此内容不适合在任何中间缓存代理上进行缓存,但浏览器中的缓存将允许用户在后续访问期间立即进行检索。
-
一般对时间敏感的内容设置例外:如果您具有对时间敏感的内容,请对上述规则进行例外设置,以便在紧急情况下不提供过时的内容。 例如,如果您的站点有一个购物车,它应该立即反映购物车中的物品。 根据内容的性质,可以在Cache-Control header中设置no-cache或no-store选项来实现此目的。
-
始终提供验证器:验证器允许刷新陈旧的内容,而无需再次下载整个资源。 设置Etag和Last-Modified标头可以使高速缓存验证其内容,并在原始位置未进行修改的情况下重新保存它,从而进一步减轻了负载。
-
为支持内容设置较长的刷新时间:为了有效利用缓存,被请求作为支持内容来满足请求的元素通常应具有较长的刷新设置。 这通常适合拉入以呈现用户请求的HTML页面的图像和CSS之类的项目。 设置延长的刷新时间并结合指纹,可使高速缓存长时间存储这些资源。 如果资产发生更改,则修改后的指纹将使缓存的项目无效,并将触发新内容的下载。 在此之前,可以将支持项目缓存到很远的将来。
-
为父级内容设置较短的刷新时间:为了使上述方案有效,所包含的项目必须具有较短的刷新时间,否则可能根本不会被缓存。 通常,这是调用其他辅助内容的HTML页面。 HTML本身将被频繁下载,从而使其能够快速响应更改。 然后可以积极地缓存支持内容。
关键是要在可能的情况下取得有利于积极缓存的平衡,同时留出机会在将来进行更改时使条目无效。 您的网站可能具有以下组合: -
积极缓存的项目
-
刷新时间短且能够重新验证的缓存项目
-
根本不应该缓存的项目
目标是在可能的情况下将内容移至第一类,同时保持可接受的准确性。
总结
花一些时间来确保您的站点具有适当的缓存策略可能会对您的站点产生重大影响。 通过缓存,您可以减少与重复提供相同内容相关的带宽成本。 您的服务器还可以使用相同的硬件来处理更多的流量。 也许最重要的是,客户将在您的网站上获得更快的体验,这可能会使他们更频繁地返回。 尽管有效的Web缓存不是灵丹妙药,但设置适当的缓存策略可以以最少的工作为您带来可观的收益。