Cloudflare
历史版本
Release 0.5
Caching

缓存机制

@opennextjs/cloudflare 支持 Next.js 缓存功能 (opens in a new tab)

Next.js 会在构建时预填充缓存。这些构建时的缓存值由 Workers Assets (opens in a new tab) 提供服务。

💡

Workers KV 采用最终一致性模型,这意味着当使用默认的 60 秒 TTL 时,更新可能需要最多 60 秒才能在全球范围内生效。

如何启用缓存

@opennextjs/cloudflare 通过项目的 OpenNext 配置支持多种缓存机制。

增量静态再生 (ISR)

Cloudflare 的 ISR 适配器使用 Workers KV (opens in a new tab) 作为 Next.js 应用的缓存。Workers KV 具有高性能 (opens in a new tab)并利用 Cloudflare 的分层缓存 (opens in a new tab)来提高缓存命中率。当您将缓存数据写入 Workers KV 时,这些数据会被存储到可以被任何 Cloudflare 节点读取的位置。这意味着您的应用可以获取数据、将其缓存到 KV 中,随后来自全球任何地方的请求都可以从这个缓存中读取。定价信息可以在 Cloudflare 文档 (opens in a new tab)中找到。

1. 创建 KV 命名空间
npx wrangler@latest kv namespace create <YOUR_NAMESPACE_NAME>
2. 将 KV 命名空间和服务绑定添加到 Worker

在应用 Worker 中使用的绑定名称为 NEXT_CACHE_WORKERS_KV。服务绑定应指向 Worker 自身的引用,其中 <WORKER_NAME> 是 wrangler 配置文件中的名称。

// wrangler.jsonc
{
  // ...
  "kv_namespaces": [
    {
      "binding": "NEXT_CACHE_WORKERS_KV",
      "id": "<BINDING_ID>",
    },
  ],
  "services": [
    {
      "binding": "NEXT_CACHE_REVALIDATION_WORKER",
      "service": "<WORKER_NAME>",
    },
  ],
}

3. 配置缓存

在项目的 OpenNext 配置中,启用 KV 缓存并设置队列。

内存队列会在需要时向页面发送重新验证请求,并支持基于每个 isolate 进行请求去重。在高流量或跨区域情况下仍可能出现重复请求。

⚠️

@opennextjs/cloudflare 提供的内存队列不完全适合生产环境部署,使用需自行承担风险!

// open-next.config.ts
import { defineCloudflareConfig } from "@opennextjs/cloudflare";
import kvIncrementalCache from "@opennextjs/cloudflare/kv-cache";
import memoryQueue from "@opennextjs/cloudflare/memory-queue";
 
export default defineCloudflareConfig({
  incrementalCache: kvIncrementalCache,
  queue: memoryQueue,
});
💡

队列的 direct 模式仅用于调试目的,不建议在生产环境中使用。我们正在积极开发适用于生产环境的解决方案。

按需重新验证

标签重新验证机制使用 Cloudflare D1 (opens in a new tab) 数据库作为后端存储,用于记录标签、路径和重新验证时间的信息。

要使用按需重新验证功能,您还需要按照 ISR 设置步骤 进行操作。

💡

如果您的应用使用 pages router,则不需要标签缓存,可以跳过此步骤。

1. 创建 D1 数据库和服务绑定

在应用 worker 中使用的绑定名称为 NEXT_CACHE_D1。服务绑定应是对您 worker 的自引用,其中 <WORKER_NAME> 是 wrangler 配置文件中的名称。

// wrangler.jsonc
{
  // ...
  "d1_databases": [
    {
      "binding": "NEXT_CACHE_D1",
      "database_id": "<DATABASE_ID>",
      "database_name": "<DATABASE_NAME>",
    },
  ],
  "services": [
    {
      "binding": "NEXT_CACHE_REVALIDATION_WORKER",
      "service": "<WORKER_NAME>",
    },
  ],
}
2. 创建标签重新验证表

D1 标签缓存需要两张表:一张用于记录标签/路径映射关系,另一张用于跟踪重新验证时间。

对于标签映射表,默认表名为 tags,可以通过设置 NEXT_CACHE_D1_TAGS_TABLE 环境变量来配置。

对于重新验证时间表,默认表名为 revalidations,可以通过设置 NEXT_CACHE_D1_REVALIDATIONS_TABLE 环境变量来配置。

可以使用 Wrangler 的 execute (opens in a new tab) 选项来创建表。请确保同时为本地开发数据库和远程数据库创建表。

wrangler d1 execute NEXT_CACHE_D1 --command "CREATE TABLE IF NOT EXISTS tags (tag TEXT NOT NULL, path TEXT NOT NULL, UNIQUE(tag, path) ON CONFLICT REPLACE)"
wrangler d1 execute NEXT_CACHE_D1 --command "CREATE TABLE IF NOT EXISTS revalidations (tag TEXT NOT NULL, revalidatedAt INTEGER NOT NULL, UNIQUE(tag) ON CONFLICT REPLACE)"
3. 配置缓存

在项目的 OpenNext 配置中,启用 KV 缓存并设置队列。队列会在需要时向页面发送重新验证请求,但不会对请求进行去重处理。

// open-next.config.ts
import { defineCloudflareConfig } from "@opennextjs/cloudflare";
import kvIncrementalCache from "@opennextjs/cloudflare/kv-cache";
import d1TagCache from "@opennextjs/cloudflare/d1-tag-cache";
import memoryQueue from "@opennextjs/cloudflare/memory-queue";
 
export default defineCloudflareConfig({
  incrementalCache: kvIncrementalCache,
  tagCache: d1TagCache,
  queue: memoryQueue,
});
4. 在部署时初始化缓存

为了确保缓存能够正确初始化并包含构建时的重新验证数据,您需要在部署步骤中设置一个运行命令。

OpenNext 会在构建过程中生成一个 SQL 文件,该文件可用于设置您的 D1 数据库。

wrangler d1 execute NEXT_CACHE_D1 --file .open-next/cloudflare/cache-assets-manifest.sql

此命令应作为每次部署的一部分运行,以确保缓存能够填充每次构建的初始重新验证数据。