用于提供“陈旧”内容的 CDN 支持/配置,在后台刷新

jam*_*s0n 7 cdn cache-control cloudflare fastly next.js

目标

始终提供来自 CDN EDGE 缓存的内容,无论内容多么陈旧。尽可能在后台刷新它。

问题

我有一个NextJS应用程序,它在服务器端呈现一些 React 组件并将它们交付给客户端。对于这个讨论,让我们只考虑我的主页,它是未经身份验证的,对每个人都是一样的。

我想要的是将服务器呈现的主页缓存在 CDN 的 EDGE 节点上,并尽可能多地或始终从该缓存中为终端客户端提供服务。

从我读到的内容来看,CDN(如 Fastly)正确支持缓存相关的标头设置,例如Surrogate-Control并且Cache-Control: stale-while-revalidate应该能够做到这一点,但实际上,我没有看到它像我期望的那样工作。我看到的是:

  • 请求错过缓存并在先前的请求应该预热它时返回到源
  • 请求从缓存提供,但在源发布新内容时永远不会更新

例子

考虑以下时间线:


[T0] - Visitor1 请求www.mysite.com- CDN 缓存完全冷,因此请求必须返回我的源(AWS Lambda)并重新计算主页。返回带有标头Surrogate-Control: max-age=100和 的响应Cache-Control: public, no-store, must-revalidate。然后访问者 1 提供了主页,但他们不得不等待高达 5 秒钟!呸!愿没有其他游客遭受同样的命运。

[T50] - 访问者 2 请求www.mysite.com- CDN 缓存包含我的文档并立即将其返回给访问者。他们只需要等待 40 毫秒!惊人的。在后台,CDN 从我的源重新获取最新版本的主页。原来它没有改变。

[T80] -www.mysite.com向主页发布新内容,使任何缓存的内容真正过时。该网站的V2现已上线!

[T110] - 访问者 1 返回到www.mysite.com- 从 CDN 的角度来看,自访问者 2 的请求以来只有 60 秒,这意味着访问者 2 发起的后台刷新应该导致缓存中主页的 <100 秒陈旧副本(尽管是 V1,而不是 V2 , 的主页)。Visitor1 从缓存中获得 60 年代陈旧的 V1 主页。这一次给 Visitor1 带来了更好的体验!本次请求对CDN缓存中的陈旧内容发起后台刷新,本次origin返回的是网站的V2版本(30s前发布的)。

[T160] - 访问者 3 访问www.mysite.com- 尽管是新访问者,但 CDN 缓存现在从访问者 1 的最近一次后台刷新触发中恢复过来。Visitor3 提供缓存的 V2 主页。

...

只要每 100max-age=100秒至少有 1 位访问者访问我的网站(因为),没有访问者会遭受到我的原点的完整往返的等待时间。


问题

1.这是对现代 CDN 的合理要求吗?我无法想象这比总是返回原点(没有 CDN 缓存)更费力,但我一直在努力从任何 CDN 提供商那里找到有关正确方法的文档。我现在正在与 Fastly 合作,但我也愿意尝试其他任何人(我首先尝试了 Cloudflare,但读到他们不支持stale-while-revalidate

2.正确的标题是什么?(假设CDN提供商支持)我打得四处都Surrogate-Control: maxage=<X>Cache-Control: public, s-maxage=<X>, stale-while-revalidate在快速度和CloudFlare的,但没有一个似乎正确地做到这一点(内原点的最大生存周期的时间内不要改变皮卡以及请求,直到有一个高速缓存未命中)。

3.如果这不受支持,是否有 API 调用可以让我将内容更新推送到我的 CDN 缓存层,有效地说“嘿,我刚刚为这个缓存键发布了新内容。就在这里!”

我可以使用 Cloudflare 工作人员使用他们的 KV 存储自己实现这种缓存,但我想在为一个似乎很常见的问题实施代码解决方案之前,我会做更多的研究。

提前致谢!

小智 -1

关于问题 3。
您可以对进行更改的每个文件使用新名称,以防止不需要的缓存,或者像您建议的那样使用 API cloudFlare 来释放缓存。
有可能,您可以在这里找到更多信息
https://api.cloudflare.com/#zone-purge-files-by-cache-tags-or-host