不同类型的 HTTP 缓存可用于不同类型的事物。我想谈谈网关缓存——或“反向代理缓存”——并考虑它们对现代动态 Web 应用程序设计的影响。

画一条假想的垂直线,位于AliceCache之间,从图的最顶部到最底部。该行是您面向互联网的公共界面。换句话说, 就Alice而言,从Cache返回的所有内容都是“您的站点” 。

Alice实际上是 Alice 的网络浏览器,或者可能是某种其他类型的 HTTP 用户代理。还有鲍勃卡罗尔。当您考虑它们对多个客户端的影响时,网关缓存最有趣。

Cache是​​一种HTTP网关缓存,像Varnish反向代理模式下的Squid、 Django的缓存框架,或者我个人最喜欢的:rack-cache。理论上,这也可以是CDN,例如Akamai

这将我们带到了Backend,一个仅使用最现代和最复杂的 Web 框架构建的动态 Web 应用程序。解释性语言、方便的路由、ORM、灵活的模板语言和其他各种废话——所有这些加起来使开发人员的工作效率惊人。换句话说,它非常慢而且臃肿……而且棒极了!可能有很多这样的进程,可能在多台机器上运行。

(一个人通常会有一个单独的Web 服务器——比如 NginxApache 或 lighttpd——可能还有一个负载平衡器也在这里,但这在很大程度上与本讨论无关,并且已从图中省略。)

过期

大多数人都非常了解到期模型。Cache-Control: max-age=N您可以通过包含或标头中的一个或两个来指定应将响应视为“新鲜”的时间长度Expires。在缓存版本达到其到期时间并变得“陈旧”之前,理解过期的缓存不会发出相同的请求。

网关缓存显着增加了在动态生成的响应中提供过期信息的好处。为了说明这一点,我们假设Alice请求一个欢迎页面:

由于缓存之前不知道欢迎页面,因此它会将请求转发到后端。后端生成响应,包括Cache-Control指示响应在十分钟内应被视为新鲜的标头。缓存然后将响应发送回Alice,同时为自己存储一个副本。

三十秒后,鲍勃出现并请求相同的欢迎页面:

缓存识别请求,提取存储的响应,发现它仍然是新鲜的,然后将缓存的响应发送回Bob,完全忽略后端。

请注意,我们在这里没有体验到显着的带宽节省——整个响应都传递给了AliceBob。我们看到了 CPU 使用率、数据库往返以及在后端生成响应所需的各种其他资源的节省。

验证

当您可以摆脱它时,过期是理想的选择。不幸的是,在很多情况下它没有意义,对于高度动态的 Web 应用程序尤其如此,在这些应用程序中,资源状态的变化可能会频繁且不可预测地发生。验证模型旨在支持这些情况。

同样,我们假设Alice对欢迎页面发出初始请求:

和标头值称为“缓存验证器”,因为缓存可以在后续请求中使用它们来验证存储Last-Modified响应的新鲜度,而无需后端生成或传输响应主体。您不需要两个验证器——任何一个都可以,尽管它们各有利弊,其详细信息超出了本文档的范围。ETag

所以鲍勃在爱丽丝之后的某个时刻出现并请求欢迎页面:

缓存看到它有一个欢迎页面的副本,但不能确定它的新鲜度,所以它需要将请求传递给后端。但是,在这样做之前,缓存将If-Modified-Since和 If-None-Match标头添加到请求中,分别将它们设置为原始响应的Last-ModifiedETag值。这些标头使请求成为有条件的。一旦后端收到请求,它会生成当前缓存验证器,根据请求中提供的值检查它们,并立即返回响应304 Not Modified而不生成响应主体。缓存已验证其副本的新鲜度,现在可以自由响应Bob

这需要与后端进行往返,但如果后端以高效的方式预先生成缓存验证器,则可以避免生成响应主体。这可能非常重要。利用验证的后端不需要两次生成相同的响应。

结合到期和验证

过期和验证模型构成了 HTTP 缓存的基础。响应可能包括过期信息、验证信息,或者两者都包括,或者两者都不包括。到目前为止,我们已经看到了每个独立的外观。还值得研究事物组合时的工作方式。

再次假设爱丽丝发出初始请求:

后端指定响应应在 60 秒内被视为新鲜,并且还包括Last-Modified缓存验证器。

三十秒后鲍勃出现了由于响应仍然是新鲜的,因此不需要验证;他直接从缓存中获取:

但是Carol在Bob之后 30 秒发出了同样的请求:

缓存在返回验证之前尽可能依赖过期。另请注意,304 Not Modified响应包括更新的过期信息,因此缓存知道在需要执行另一个验证请求之前还有 60 秒。

更多的

此处显示的基本机制构成了 HTTP 缓存的概念基础——更不用说REST 定义的缓存架构约束了。当然,还有更多:缓存的行为可以通过附加Cache-Control指令进一步约束,并且Vary标头会根据后续请求的标头缩小响应的缓存适用性。要更全面地了解 HTTP 缓存,我建议阅读 Mark Nottingham 的出色的Web 作者和网站管理员缓存教程。Paul James 的HTTP Caching也很不错,而且更短一些。当然,强烈推荐RFC 2616 的相关部分。

缓存做的事情
标签: