Workers Cache 引发关注,或改变数据处理模式
速览
Workers Cache 近期在科技资讯中亮相,其具体定义尚不明确。该技术可能针对分布式环境下的缓存优化,对AI推理、大数据处理等场景具有潜在价值。业界正密切关注其对工作流效率的影响。
AI 深度解读
背景
Cloudflare 在 2017 年推出 Workers 时,其定位是在请求到达源站之前,在 Cloudflare 网络上运行代码以改写请求。当时 Worker 位于缓存和源站之前,可以添加请求头、改写 URL、做 A/B 测试或过滤流量。这个架构对于“给源站加一层代理”的场景非常合理。
但世界变了。Workers 不再只是附加在源站上的配件,它本身变成了源站。Astro、TanStack Start、Next.js、Remix、SvelteKit 等框架都提供了 Cloudflare 适配器,将应用构建为 Worker 运行。这些 Worker 背后不再有传统源站——Worker 就是服务器。
当 Worker 成为源站时,原本的架构意味着没有任何东西可以为它缓存。每一次请求都会执行你的代码,即使响应与一秒前返回的完全相同。Workers 运行时足够快,能够处理每秒几千万次请求,但“快到来得及渲染每一次请求”仍然会让每个页面加载产生延迟,每次调用都会消耗 CPU 时间。对服务端渲染的应用而言,每一次页面加载本质上都是一次渲染。
这就是 Workers Cache 要解决的问题。
核心内容
Workers Cache 是一个分层的缓存层,位于 Worker 之前。通过一行 Wrangler 配置和开发者已经熟悉的 Cache-Control 头即可启用。
当 Workers Cache 启用时,每个可缓存的请求会首先到达 Cloudflare 的缓存。如果存在有效的缓存响应,Cloudflare 直接返回——Worker 不运行,不计费 CPU 时间。如果缓存未命中,Worker 运行一次,若响应可缓存,Cloudflare 会将其存储起来,供下一次请求使用。此后全球任何位置的请求都可以直接命中缓存。
启用配置只需在 wrangler.toml 中添加一个配置块:
{
"name": "my-worker",
"main": "src/index.ts",
"compatibility_date": "2026-05-01",
"cache": {
"enabled": true
}
}
之后,按照 HTTP 标准的方式控制缓存——在响应上设置头:
return new Response(body, {
headers: {
"Cache-Control": "public, max-age=300, stale-while-revalidate=3600",
"Cache-Tag": "products,product:123",
},
});
当内容变化时,Worker 可以按标签清除自己的缓存:
await ctx.cache.purge({ tags: ["product:123"] });
这就是完整的 API。不需要配置 Zone、不需要设置规则引擎、不需要单独预置缓存、不需要登录另一个产品。Worker 的代码就是配置界面,缓存跟随 Worker 运行的地方——无论是自定义域名、workers.dev、服务绑定背后、预览环境,还是 Workers for Platforms 租户。一个 Worker,一个缓存,一次配置。
表面上看很简单,底层支撑很多:全网络的分层缓存、完整的 stale-while-revalidate 支持、通过 Vary 进行内容协商、通过 ctx.props 实现多租户安全的缓存键、通过标签或路径前缀进行编程式清除,以及——我们认为最大的解锁——缓存位于每一个 Worker 入口点之前(不只是公开入口点),并且每个入口点可以独立控制是否缓存。这意味着你可以在应用结构内直接组合缓存:一系列入口点,在任意位置插入缓存阶段,由两侧的代码配置。
Workers Cache 今天对所有计划的 Worker 开放,在 Wrangler 中启用。
stale-while-revalidate 让体验“瞬时”
stale-while-revalidate 指令告诉 Cloudflare:当缓存响应过期后,允许立即返回过期副本,同时在后台刷新响应。Cloudflare 今年早些时候已完整支持该指令。正是这个指令将“我们把 Worker 缓存了”变成“你的 Worker 站点感觉像静态站点”。
如果没有它,缓存条目过期后的第一个请求必须等待 Worker 从头渲染页面,用户会感知到延迟。有了它,过期后的第一个请求立即拿到过期页面(同时附带 Cf-Cache-Status: UPDATING 头),Worker 在后台运行重新填充缓存。每一个用户,包括那个触发了刷新的用户,都得到缓存级别的响应速度。
实践中的代码:
export default {
async fetch(request) {
const html = await renderPage(request);
return new Response(html, {
headers: {
"Content-Type": "text/html; charset=utf-8",
"Cache-Control": "public, max-age=300, stale-while-revalidate=3600",
},
});
},
};
模型解释:
- 新鲜窗口(
max-age):Cloudflare 直接返回缓存响应,Worker 不运行。 - 过期窗口(
stale-while-revalidate):Cloudflare 返回缓存响应,Worker 在后台运行刷新,没有用户等待。 - 两个窗口之外:Cloudflare 运行 Worker 生成新响应,用户等待这一次渲染。
窗口由你设定。对于几分钟更新一次的产品目录,max-age=300, stale-while-revalidate=3600 意味着访问者基本不等待,Worker 仍然足够频繁运行以保持内容新鲜。对于几乎不变化的博客归档,max-age=86400, stale-while-revalidate=2592000 意味着每个页面每天只渲染一次。
全新页面的第一次请求是唯一需要承受完整渲染成本的请求。之后,该页面对于访问者就像静态输出一样,而 Worker 仍然拥有生成页面的控制权。
一个 URL,多种表示:Vary 起作用
真实应用很少向所有客户端返回相同的字节。同一个产品页面可能对浏览器返回 HTML,对 API 客户端返回 JSON;同一张图片可能对支持 WebP 的客户端返回 WebP,对其他返回 JPEG;同一主页可能根据用户偏好或 Accept 头返回不同版本。
Workers Cache 完全支持 Vary 响应头。你可以根据请求头(如 Accept、Accept-Encoding、Cookie 等)缓存不同的表示,每个表示独立存储和刷新。这意味着 Worker 可以按需渲染不同版本,而后续相同特征的请求直接命中对应缓存。
按入口点细粒度控制
Workers Cache 的一个关键设计是:缓存位于每一个 Worker 入口点之前,包括通过服务绑定调用的内部入口点。你可以为每个入口点单独启用或禁用缓存,并且每个入口点可以有不同的缓存配置。这意味着你可以将缓存直接嵌入应用架构中——例如,一个入口点负责认证,其输出不缓存;下一个入口点负责渲染公共页面,启用缓存。整个链路由代码定义,缓存阶段按需插入。
关键要点
- Workers Cache 是放在 Worker 前面的分层缓存,取代了之前 Worker 放在缓存前面的架构。
- 启用只需在 Wrangler 配置中添加
"cache": {"enabled": true},缓存行为通过标准的Cache-Control头控制。 - 缓存命中时 Worker 完全不运行,不消耗 CPU 时间;缓存未命中时 Worker 运行一次,响应被缓存供后续使用。
- 支持
stale-while-revalidate:过期后立即返回旧缓存,同时在后台刷新,用户无感知。 - 支持
Vary进行内容协商,同一 URL 可缓存多个不同表示。 - 支持按标签或路径前缀进行编程式缓存清除:
ctx.cache.purge({ tags: [...] })。 - 缓存跟随 Worker,无需单独配置 Zone 或规则引擎;一个 Worker 一个缓存。
- 缓存位于 每一个 Worker 入口点之前(包括公开和内部入口点),每个入口点可单独控制是否缓存。
- 该功能适用于所有计划的 Worker,已可在 Wrangler 中启用。
意义与影响
Workers Cache 填补了服务端渲染在 Cloudflare Workers 上的关键空白。此前开发者不得不在两种不令人满意的方案中二选一:要么在构建时预渲染所有内容(静态站点生成),每次修改都需要完整重建和部署(大型站点需要 5-10 分钟甚至更久);要么每个请求都动态渲染,虽能保证内容最新,但每个页面加载都付出渲染延迟和 CPU 成本。
Workers Cache 提供了第三种路径:按需服务端渲染、缓存渲染结果、按自定义 TTL
