跳转到内容
本站为社区维护的非官方中文翻译,与 Cloudflare, Inc. 无关联。本站不提供账户登录,请勿在任何非官方站点输入您的 Cloudflare 账户信息。官方文档:developers.cloudflare.com

规划迁移到 Sandbox SDK 1.0

最后更新 查看 MarkdownAgent 设置

本页比较将 sandbox 从 Sandbox SDK 0.12 迁移到 1.0 的两种方式,然后通过一次部署迁移所有 sandbox。你无法撤销将 sandbox 切换到 1.0 的那次部署。

开始之前

  • 你的应用运行的是 @cloudflare/sandbox 0.12.14。
  • 你的 1.0 类已经写好。有关该类,请参阅 替换 Sandbox 类。
  • 你有一份带有独立 Wrangler 配置文件的预发布 Worker。在该文件中为 Worker 设置不同的 name,并为每个容器设置不同的 name,因为 wrangler deploy 的 --name 选项不会重命名容器应用。

选择路径

你可以通过以下两种方式之一迁移:

路径 会发生什么 适合
就地迁移 一次部署将所有 sandbox 迁移到 1.0。在 0.12 容器中运行的命令会结束,这些容器中的文件不会带过来。 生命周期短或重新创建成本低的 sandbox
并排迁移 1.0 类与 0.12 类在同一 Worker 中并排运行。你的代码迁移每个 sandbox,当没有剩余 0.12 sandbox 时再删除 0.12 类。 用户会返回的长期 sandbox

两种路径都不能用渐进式部署拆分流量。Wrangler 会拒绝混合这两个版本的部署,并出现此错误:

All Worker Versions in a multi-version deployment must declare identical Durable Object-managed Container applications.

先在预发布 Worker 上排练你的路径(其中已有正在运行的 sandbox),然后再在生产环境中执行。本页其余部分按就地迁移进行。另一条路径请参阅 并排迁移 sandbox。

切换对正在运行的 sandbox 的影响

当将类迁移到 scheduling_policy: "durable_object" 的部署上线时,切换就会发生。0.12 sandbox 的各部分会如下变化:

部分 切换时
正在运行的容器 继续在旧容器应用中运行。部署后的短时间内,你的 Durable Object 仍会报告 running 为 true,exec() 和 getTcpPort() 仍会到达 0.12 容器。之后 running 为 false,你的代码会启动 1.0 容器。
文件 留在旧容器中。新容器启动时没有它们。
正在运行的命令 很快结束。在完成时返回结果的命令会失败并出现 HTTP 500。流式输出会以 HTTP 200 停止且没有错误。
WebSockets 停止投递数据。客户端收不到 close frame。
待处理的 alarm 为每个曾处于活动状态的 sandbox 调用一次你的 1.0 alarm() handler。
schedule() 回调 永远不会运行。
0.12 存储键 保留 Durable Object 存储。迁移预览 URL、隧道和出站规则的页面会读取 portTokens、tunnels、tunnels:meta 和 OUTBOUND_CONFIGURATION。

通过一次部署迁移所有 sandbox

  1. 让你的 alarm() handler 在行动前检查自己的状态。0.12 在容器运行时会保持 alarm 已设置,切换后该 alarm 会调用你的 handler。如果 handler 抛出错误,平台会以退避方式重试。在此示例中,除非 nextCheckpoint 时间已过,否则 handler 会返回:

    src/index.tsts
    export class MySandbox extends DurableObject<Env> {
        // ...
    
        async alarm(): Promise<void> {
            // A 0.12 alarm can call this handler once after the switch.
            const due = await this.ctx.storage.get<number>("nextCheckpoint");
    
            if (due === undefined || due > Date.now()) {
                return;
            }
    
            await this.checkpoint();
        }
    }

    如果你的类没有 alarm() handler,每个待处理 alarm 都会在日志中以内部错误失败一次,然后被清除。

  2. 替换 schedule() 调用。0.12 将已调度的回调存储在 1.0 不会读取的表中。从你的类使用 this.ctx.storage.setAlarm() 设置下一次运行,并在 alarm() 中完成工作。一个 Durable Object 只有一个 alarm,因此这就是第 1 步中的 handler。要替换多个调度,请存储每次运行的时间,将 alarm 设置为最早的那次,并在 alarm() 中运行所有到期任务。更多信息请参阅 Alarms。

  3. 让客户端为静默套接字做好准备。打开的终端和预览 WebSocket 在切换时会停止接收数据,浏览器看不到它们关闭。让客户端在套接字一段时间没有收到数据时重连,或告诉用户在部署后重新加载。

  4. 保存用户需要的文件。0.12 容器停止后,其文件就会消失;部署后短暂期间内 1.0 代码仍可访问旧容器,这并不能作为复制文件的方式。部署前,请使用 0.12 createBackup() 保存文件。切换后,请按照迁移备份中的说明恢复文件。

  5. 先在预发布 Worker 上排练。在那里有正在运行的 sandbox 且客户端已连接的情况下,按第 6 步和第 7 步所述将 1.0 版本上传并部署到预发布 Worker。检查切换后应用发出的请求是否正常工作。

  6. 上传 1.0 版本:

    npx wrangler versions upload

    上传会构建 1.0 镜像并创建新的容器应用。正在服务流量的版本不会改变。记下 Wrangler 打印的版本 ID。

  7. 在没有长时间运行的命令时部署该版本。

    将 <VERSION_ID> 替换为上传得到的 ID:

    npx wrangler versions deploy <VERSION_ID>@100% -y

检查迁移

从应用程序向 sandbox 发送请求,例如运行命令或读取文件。每个 Durable Object 会在首次请求时启动 1.0 容器(此时 running 为 false)。部署后短时间内,请求仍可能到达 0.12 容器,并在 0.12 镜像中运行命令。请在部署后等待几分钟再检查。列出账户中的容器应用:

npx wrangler containers list

列表会显示你设置了 name 的新应用。旧应用仍在。Wrangler 根据你的 Worker 和类名命名它,例如 my-worker-sandbox。

清理

删除旧容器应用。将 <OLD_APPLICATION_ID> 替换为列表中的 ID:

npx wrangler containers delete <OLD_APPLICATION_ID>

旧应用会继续运行其容器并为它们计费,直到你删除它。删除它会停止 0.12 启动的容器并删除它们的文件。Durable Objects 及其存储会保留。

0.12 写入的键会继续保留在每个 Durable Object 的存储中。只要你的类仍会读取这些键(例如迁移预览 URL、隧道和出站规则的页面),就请保留 portTokens、tunnels、tunnels:meta 和 OUTBOUND_CONFIGURATION。如果删除其他键,请在 delete() 调用中逐一指定键。不要调用 deleteAll(),它还会删除你自己的键和仍需转换的 0.12 备份句柄。

相关资源

这篇文档对您有帮助吗?