缓存
@opennextjs/cloudflare 支持 缓存 (opens in a new tab)。
如何启用缓存
@opennextjs/cloudflare 通过项目的 OpenNext 配置支持多种缓存机制。
增量静态再生 (ISR)
增量缓存有两种存储选项可供选择。
- Workers KV: 一种 快速 (opens in a new tab) 存储,并使用 Cloudflare 的 分层缓存 (opens in a new tab) 来提高缓存命中率。当你将缓存数据写入 Workers KV 时,你写入的是任何 Cloudflare 位置都可以读取的存储。这意味着你的应用可以获取数据,将其缓存到 KV 中,然后随后来自世界各地的请求都可以从此缓存中读取。构建时的值由 Workers Assets (opens in a new tab) 提供。定价信息可在 Cloudflare 文档 (opens in a new tab) 中找到。
- R2 对象存储: 一种 具有成本效益 (opens in a new tab) 的 S3 兼容对象存储选项,适用于大量非结构化数据。数据存储在单个区域,这意味着缓存交互可能较慢——这可以通过区域缓存来缓解。
Workers KV 是最终一致的,这意味着当使用默认的 60 秒 TTL 时,更新可能需要长达 60 秒才能在全球范围内反映出来。
1. 创建 KV 命名空间
npx wrangler@latest kv namespace create <YOUR_NAMESPACE_NAME>2. 将 KV 命名空间和服务绑定添加到你的 Worker
你的应用 worker 中使用的绑定名称是 NEXT_INC_CACHE_KV。
WORKER_SELF_REFERENCE 服务绑定应该是对你的 worker 的自引用,其中 <WORKER_NAME> 是你的 wrangler 配置文件中的名称。
// wrangler.jsonc
{
// ...
"name": "<WORKER_NAME>",
"kv_namespaces": [
{
"binding": "NEXT_INC_CACHE_KV",
"id": "<BINDING_ID>",
},
],
"services": [
{
"binding": "WORKER_SELF_REFERENCE",
"service": "<WORKER_NAME>",
},
],
}3. 配置缓存
在你的项目 OpenNext 配置中,启用 KV 缓存。
// open-next.config.ts
import { defineCloudflareConfig } from "@opennextjs/cloudflare";
import kvIncrementalCache from "@opennextjs/cloudflare/overrides/incremental-cache/kv-incremental-cache";
// ...
export default defineCloudflareConfig({
incrementalCache: kvIncrementalCache,
// ...
});4. 配置队列
在你的项目 OpenNext 配置中,启用缓存并设置队列。
Durable Object 队列将在需要时向页面发送重新验证请求,并提供请求去重支持。 默认情况下,最多会有 10 个 Durable Object 队列实例,它们每个可以并行处理最多 5 个请求,最多支持 50 个并发 ISR 重新验证。
// open-next.config.ts
import { defineCloudflareConfig } from "@opennextjs/cloudflare";
// ...
import doQueue from "@opennextjs/cloudflare/overrides/queue/do-queue";
export default defineCloudflareConfig({
// ...
queue: doQueue,
});你还需要在 wrangler.jsonc 文件中添加一些绑定。
"durable_objects": {
"bindings": [
{
"name": "NEXT_CACHE_DO_QUEUE",
"class_name": "DurableObjectQueueHandler"
}
]
},
"migrations": [
{
"tag": "v1",
"new_sqlite_classes": ["DurableObjectQueueHandler"]
}
],你可以使用环境变量自定义队列的行为:
- 一个 durable object 实例同时可以处理的最大重新验证数量 (
NEXT_CACHE_DO_QUEUE_MAX_REVALIDATION) - 重新验证在被视为失败之前可以花费的最大时间(毫秒) (
NEXT_CACHE_DO_QUEUE_REVALIDATION_TIMEOUT_MS) - 如果重新验证失败,再次尝试重新验证的时间间隔。如果再次失败,它将指数退避直到达到最大重试间隔 (
NEXT_CACHE_DO_QUEUE_RETRY_INTERVAL_MS) - 重新验证路径可以尝试的最大次数 (
NEXT_CACHE_DO_QUEUE_MAX_NUM_REVALIDATIONS) - 禁用此 durable object 的 SQLite。仅当你的增量缓存不是最终一致时才应使用它 (
NEXT_CACHE_DO_QUEUE_DISABLE_SQLITE)
队列还有 2 种额外模式可供使用:direct 和内存队列
-
内存队列将去重请求,但仅基于每个 isolate。它不完全适合生产部署,你可以自担风险使用它!
-
队列的
direct模式旨在用于调试目的,不建议在生产中使用。它仅在预览模式下工作(即wrangler dev)对于使用 Page Router 的应用,
res.revalidate需要提供名为WORKER_SELF_REFERENCE的自引用服务绑定。
按需重新验证
标签重新验证机制可以使用 Cloudflare D1 (opens in a new tab) 数据库或带有 SqliteStorage 的 Durable Objects (opens in a new tab) 作为其后端存储,用于存储有关标签、路径和重新验证时间的信息。
要使用按需重新验证,你还应该遵循 ISR 设置步骤。
如果你的应用 仅 使用 pages router,则不需要标签缓存,应跳过此步骤。
如果你的应用不使用 revalidateTag 也不使用 revalidatePath,你也可以跳过此步骤。
标签缓存有 3 种不同的选项可供选择:d1NextTagCache、doShardedTagCache 和 d1TagCache。
选择哪一个应基于两个关键因素:
- 预期负载:考虑你预期的流量或数据量。
revalidateTag/revalidatePath的使用:评估这些功能将被使用的频率。
如果其中任何一个因素很重要,建议选择分片数据库。此外,结合区域缓存可以进一步增强性能。
1. 创建 D1 数据库和服务绑定
你的应用 worker 中使用的绑定名称是 NEXT_TAG_CACHE_D1。WORKER_SELF_REFERENCE 服务绑定应该是对你的 worker 的自引用,其中 <WORKER_NAME> 是你的 wrangler 配置文件中的名称。
// wrangler.jsonc
{
// ...
"d1_databases": [
{
"binding": "NEXT_TAG_CACHE_D1",
"database_id": "<DATABASE_ID>",
"database_name": "<DATABASE_NAME>",
},
],
"services": [
{
"binding": "WORKER_SELF_REFERENCE",
"service": "<WORKER_NAME>",
},
],
}2. 为标签重新验证创建表
D1 标签缓存需要一个 revalidations 表来跟踪按需重新验证时间。
3. 配置缓存
在你的项目 OpenNext 配置中,启用 KV 缓存并设置队列(见上文)。队列将在需要时向页面发送重新验证请求,但不会去重请求。
// open-next.config.ts
import { defineCloudflareConfig } from "@opennextjs/cloudflare";
import kvIncrementalCache from "@opennextjs/cloudflare/kv-cache";
import d1NextTagCache from "@opennextjs/cloudflare/d1-next-tag-cache";
import memoryQueue from "@opennextjs/cloudflare/memory-queue";
export default defineCloudflareConfig({
incrementalCache: kvIncrementalCache,
tagCache: d1NextTagCache,
queue: memoryQueue,
});