给 Web 开发者与管理员的缓存指南

Web 缓存是什么?为什么要使用缓存?

Web 缓存处于服务器(也称为源服务器)和客户端之间,监视请求并保存响应的副本,比如 HTML 页面,图片和文件等(统称为表述)。如果之后有对同一个 URL 的新请求,它会使用自己保存的内容来响应,而不是再次请求源服务器来获取内容。

使用 Web 缓存主要有下面两个原因:

  • 减少延迟 —— 因为响应请求的内容来自缓存(距客户端较近)而不是源服务器,它会花较少的时间来获得表述并将他们呈现出来。这使得 Web 看起来具有良好的响应速度。
  • 减少网络传输 —— 由于复用了表述,它可以减少客户端使用的带宽总量。如果客户需要为流量付费,这就意味着省钱。缓存会降低对带宽的要求,也降低处理难度。

Web 缓存的种类

浏览器缓存

你在查看现代 Web 浏览器(比如 IE、Safari 或 Mazilla)选项的时候,可能会看到“缓存”设置。这个选项让你配置一部分硬盘空间来保存你看过的表述。浏览器缓存的规则相当简单。它通常会在一次会话(即当前浏览器中第一次调用)中检查表述是否最新。

这个缓存在用户使用“回退”按钮或者点击一个浏览过的链接时会特别有用。而且,如果你在网站的各个页面中浏览相同的图片,他们几乎能马上从缓存中加载出来。

代理缓存

Web 代理缓存的工作原理相同,但规模更大。代理以同样的方式为成百上千的用户服务;大公司和 ISP 常常把代码缓存建立在防火墙之上,也可能是以独立设备的形式存在(也称为中间设备)。

代理缓存即不是客户端的一部分,也不是服务器的一部分,而是在网络之外,必须以某种方式把请求路由过去。其中一种方式是手工修改浏览器代理设备,指定要使用的代码;另一种方式是拦截。拦截式代理会根据其自身的基础网络重定向 Web 请求,不需要在客户端配置,客户端甚至不知道它们的存在。

代理缓存是一种共享缓存,通常不只是一个用户,而是大量用户在使用代理缓存。正因为如此,他们特别擅长降低延迟和网络传输量。这是因为众人都需要的表述会被多次重复使用。

网关缓存

网关缓存又名“反向代理缓存”或“替代缓存”。网关缓存也是一种中介,它他们不是由网络管理员部署以节约带宽,而是由网站管理员自己部署,使其站点更具伸缩性、可靠性以及拥有更好的性能。

很多方法都可以把请求路由到网关缓存,但常见的方法是使用负载均衡器让他们对于客户来说,看起来就跟源服务器一样。

内容分发网络(CDN)在整个 Internet(或它的一部分)中分发网关缓存,并将其出售给对此感兴趣的网站。Speedera 和 Akamai 都是 CDN。

本教程主要关注浏览器和代理缓存,不过其中一些信息也适用于对网关缓存有兴趣的人。

Web缓存对我有坏处么?我为什么要帮助它们?

Web缓存是互联网中误解最深的技术之一。因为代理缓存可以隐藏使用网站的用户,所以网站管理员特别害怕失去对他们的站点的控制,这会使得他们很难去知道是谁在使用他们的站点。

然而不幸的是,即使没有Web缓存,网络上也有非常多的因素可以保证管理员精确的知道一个用户如何使用他们的站点。如果这是你非常关注的问题的话,这篇手册将会指导你如何在站点没有不友好的缓存机制的情况下获取你需要的统计信息。

另一个问题是,缓存可以提供已经失去时效性或者无效的数据给请求方。这篇手册将会演示如何配置你的服务端的服务来控制数据内容的缓存方式。

另一方面,如果你把站点规划的非常好,那么缓存将会使得站点的加载速度更快,同时也会减轻服务端和网络线路的负担。这两者之间的区别是非常显而易见的:一个没有使用缓存的站点可能需要数秒时间来完成页面的加载和展示,而另一个借助了缓存机制的网站可能在瞬间就完成了页面加载和展示。而用户会更喜欢加载速度迅速的站点,同时也会更加频繁的访问这些加载迅速的站点。

内容传递网络 (CDNs) 是一个非常有意思的发展产物,和通常的代理缓存不同的是,CDNs 的网关缓存和被缓存站点的关注点是一致的,所以上述的问题都得到了处理和解决。然而,即便你使用了 CDNs ,你仍然要知道在下游还是会存在代理和浏览器缓存的。

我们可以这样想一下:许多大型的互联网公司为了让他们的用户可以在使用其提供的服务时得到最快速的响应,会斥资数百万美元在世界范围内建立许多服务器机群来复制存储他们的数据内容。其实,缓存也能做这些事情,而且,相对来说缓存离最终的使用用户会更近。最好的一点是,你根本不用为此支付任何费用。

而事实是,不管你愿意与否,代理和浏览器缓存都会被使用在某个环节中。如果你没有正确的配置站点的缓存相关配置,站点数据将会按照默认的缓存管理员的配置被缓存下来。

Web缓存是如何工作的?

所有的缓存都有一系列用来决定什么时候从缓存中提供内容的规则。如果可能的话,其中的一些规则被放置在了协议中(HTTP 1.0和1.1),而另一些则由缓存的管理员(诸如浏览器缓存的用户,或者代理管理员)来设置。

通常情况下,下面列出的这些规则是最常用到的规则集(不用担心你不了解规则的详细嘻嘻,之后会详细地对这些规则作出解释):

  1. 如果响应的头部通知缓存不要保存当前响应内容,那么缓存就不会缓存当前响应。
  2. 如果是一个授权的或者加密的请求(例如HTTPS),那么共享缓存将不会保存相关数据内容。
  3. 在下述场景中,我们认为被缓存的内容是最新的(意味着不需要源服务端的检查就可以被发送给客户端),故而数据内容会直接从缓存中提供且不需要源服务端的校验:
  • 缓存内容由过期时间或者其他的生存期控制机制,且缓存内容仍在生存有效期内;
  • 如果缓存服务近期对外提供了数据内容,且该内容在很久之前就被修改了。
  1. 如果内容已经过时了,源服务端会要求对其进行验证,或者通知缓存服务这份缓存的内容是否仍然有效。
  2. 在类似于网络中断这样的场景中,缓存可以对外提供过时的响应数据而不必和源服务器进行校验和确认。

如果在响应中没有相应的验证器( ETag 或者 Last-Modified 头部),且也没有明确的刷新信息,则这种数据通常但不总是的会被视为不可缓存的数据。

综合来看,刷新和验证是缓存可以正常有效的保存内容的最重要途径。新的数据内容可以可靠的快速的从缓存中得到,与此同时一个经过验证的表述则避免了在没有发生变更的情况下被再次完整的发送出去。

如何(以及如何不)控制缓存

有一些工具可以让网站设计人员和网站管理员来调整缓存对其站点的操作,这可能会使得服务器的配置发生变更,但是这些变更都是有价值的。对于如何在服务器上使用这些工具,在实现这一章节会详细阐述。

给 Web 开发者与管理员的缓存指南

相关推荐