AWS
主要组件
服务器
Node

这是 SSR、ISR 或 SSG 路由的主入口点。 本文档仅适用于 Node 运行时环境。

ISR/SSG

在独立模式下,Next.js 会在构建过程中预先生成 ISR/SSG 缓存。在运行时,NextServer 需要这些缓存文件存在于本地服务器上。当服务器运行在单个 Web 服务器机器上时,这种方式可以高效地在所有请求间共享缓存。但在无服务器环境中,缓存需要集中存储在所有服务器 Lambda 函数实例都能访问的位置。默认情况下使用 S3 作为集中存储位置。

为实现这一机制:

  • ISR 缓存文件会被排除在 server-function 打包文件之外,转而上传到缓存存储桶
  • 通过在 next.config.js 中配置 incrementalCacheHandlerPath (opens in a new tab) 字段替换默认的缓存处理器
  • 自定义缓存处理器默认会管理 S3 上的缓存文件,处理读写操作
  • 由于我们使用 FIFO 队列,如果需要同时处理多个重新验证请求,我们需要不同的消息组 ID。我们基于路由路径为每个重新验证请求生成消息组 ID,这确保同一路由的重新验证请求只会被处理一次。你可以使用 MAX_REVALIDATE_CONCURRENCY 环境变量来控制同时处理的重新验证请求数量,默认值为 10
  • revalidation-function 会从队列轮询消息,并向路由发送带有 x-prerender-revalidate 头的 HEAD 请求
  • server-function 接收到 HEAD 请求后会重新验证缓存
  • 标签在 DynamoDB 表中采用不同的处理方式。我们使用单独的表来存储每个路由的标签,自定义缓存处理器在更新缓存时会同步更新表中的标签

ISR(增量静态再生)请求的生命周期(针对过期页面)

  1. Cloudfront 接收到页面请求。假设该页面在 Cloudfront 中已过期。
  2. Cloudfront 在后台将请求转发给 server-function,但仍返回缓存版本。
  3. server-function 检查增量缓存。如果页面已过期,它会将过期响应返回给 Cloudfront,同时向重新验证队列发送消息以触发后台重新验证。它还会将 cache-control 标头更改为 s-maxage=2, stale-while-revalidate=2592000
  4. 2 秒后,同一页面收到新请求。Cloudfront 将缓存版本返回给用户,并将请求转发给 server-function
  5. 如果重新验证已完成,server-function 将更新缓存并将更新后的响应发送回 Cloudfront。后续请求将获得更新后的版本。否则,流程将回到步骤 3。

使用 revalidateTag 重新验证的 SSG(静态站点生成)请求的生命周期

  1. 您使用 revalidateTagrevalidatePath 重新验证页面。您还应使 Cloudfront 中的缓存失效。
  2. Cloudfront 接收到页面请求。
  3. Cloudfront 将请求转发给 server-function
  4. server-function 先检查增量缓存,然后检查标签缓存。如果页面在标签缓存中已过期,它将立即触发重新验证,并将更新后的响应发送回 Cloudfront。
  5. 用户将收到页面的更新版本,且响应头 x-next-cache 将被设置为 MISS

特殊覆盖配置

所有这些覆盖配置都是基于单个函数应用的。您需要为每个要覆盖的函数单独指定它们。

增量缓存 (Incremental Cache)

增量缓存用于存储 ISR SSG 页面的结果以及 fetch 缓存。默认情况下,OpenNext 使用 S3 作为默认的增量缓存。

您可以通过在 open-next.config.ts 文件中设置 override.incrementalCache 属性来覆盖默认缓存。可参考此处 (opens in a new tab)查看预期类型。

默认 S3 增量缓存

默认的 S3 增量缓存使用 @aws-sdk/client-s3 与 S3 存储桶交互。它需要具备读写存储桶的适当权限。

S3 中的文件应遵循以下结构:

  • Key_Prefix/BUILD_ID/path/to/page.cache - 用于页面缓存
  • Key_Prefix/__fetch/BUILD_ID/fetch-cache-key - 用于 fetch 缓存

默认 S3 增量缓存可通过以下环境变量配置:

环境变量
  • CACHE_BUCKET_REGION: S3 存储桶所在区域
  • CACHE_BUCKET_NAME: S3 存储桶名称
  • CACHE_BUCKET_KEY_PREFIX: S3 存储桶中键的前缀 - 可选
  • AWS_SDK_S3_MAX_ATTEMPTS: 访问 S3 存储桶的最大尝试次数 - 可选

标签缓存 (Tag Cache)

标签缓存用于存储 ISR/SSG 页面以及 fetch 缓存的标签。默认情况下,OpenNext 使用 DynamoDB 作为默认的增量缓存。

您可以通过在 open-next.config.ts 文件中设置 override.tagCache 属性来覆盖默认缓存。可参考此处 (opens in a new tab)查看预期类型。

默认 DynamoDB 标签缓存

默认的 DynamoDB 标签缓存使用 @aws-sdk/client-dynamodb 与 DynamoDB 表进行交互。它需要具备读写该表的适当权限。

DynamoDB 中的标签应遵循以下结构:

type Tag = {
  path: string; // 页面路径
  tag: string; // 页面标签
  revalidatedAt: number; // 页面重新验证的时间戳
};

我们使用名为 revalidate 的索引,其中 path 作为分区键,revalidatedAt 作为排序键。 需要预先填充正在生成的页面的标签。

默认的 DynamoDB 标签缓存可以通过以下环境变量进行配置:

环境变量
  • CACHE_BUCKET_REGION: DynamoDB 表所在区域
  • CACHE_DYNAMO_TABLE: DynamoDB 表名称
  • AWS_SDK_DYNAMODB_MAX_ATTEMPTS: 访问 DynamoDB 表的最大尝试次数 - 可选
  • DYNAMO_BATCH_WRITE_COMMAND_CONCURRENCY: 并发批量写入 DynamoDB 表的命令数量 - 可选,默认为 4

重新验证队列

重新验证队列用于存储需要重新验证的页面。 默认情况下,OpenNext 使用 SQS 作为默认的重新验证队列。

您可以通过在 open-next.config.ts 文件中设置 override.queue 属性来覆盖默认队列。

以下是队列覆盖的预期类型:

interface QueueMessage {
  MessageDeduplicationId: string;
  MessageBody: {
    host: string;
    url: string;
  };
  MessageGroupId: string;
}
 
export interface Queue {
  send(message: QueueMessage): Promise<void>;
  name: string;
}

当页面被标记为 STALE 时,将调用 send 函数。您不必在此处使用队列,可以使用任何其他机制将消息发送到重新验证工作器,甚至可以在同一进程中执行重新验证。

共享环境变量

  • MAX_REVALIDATE_CONCURRENCY: 同时处理的重验证请求数量 - 可选 默认为10
默认SQS重验证队列

默认SQS重验证队列使用@aws-sdk/client-sqs与SQS队列交互。需要具备向队列发送消息的适当权限。

可以通过以下环境变量配置默认SQS重验证队列:

环境变量
  • REVALIDATION_QUEUE_REGION: SQS队列所在区域
  • REVALIDATION_QUEUE_URL: SQS队列的URL