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

迁移到 Durable Object 调度策略

最后更新 查看 MarkdownAgent 设置

你无法更改现有 Container 应用的调度策略。要从 default 策略迁移到 durable_object 策略,请创建替换 Container 应用并将流量切换过去。

替换应用必须使用新的 Durable Object 类和命名空间。旧应用和替换应用不能附加到同一个 Durable Object 命名空间。

开始之前

  • 替换 Container 类。 Container 类 不支持 durable_object 策略。如果你现有的类扩展 Container,替换类必须直接使用 Durable Object Container API。重建应用依赖的任何 Container 类辅助方法,例如端口就绪检查、请求代理和休眠超时。请参阅迁移到 Durable Object Container API。
  • 检查 Worker 如何声明 Durable Object 类。 Worker 使用 exports 字段 或旧版 migrations 数组 其中之一,不能同时使用。用 Worker 已在使用的同一机制声明替换类。从 migrations 迁移到 exports 无法撤销。如果你想迁移,请将其作为单独的变更。请参阅从旧版 migrations 流程迁移。
  • 将外部镜像移到 Cloudflare 托管 registry。 使用 durable_object 策略的具名镜像必须使用 Dockerfile,或 Cloudflare 托管 registry 中按 digest 固定的引用。如果现有 image 引用 Docker Hub、Amazon ECR 或 Google Artifact Registry,请先将该镜像推送到 Cloudflare 托管 registry。

配置变更

将现有应用配置映射到其 durable_object 等效项:

default 策略 durable_object 策略
image(Dockerfile 路径) 具名 images 条目上的 dockerfile,通过 ctx.container.start() 选择
image(registry 引用) 具名 images 条目上的 image。必须是 Cloudflare 托管 registry 中按 digest 固定的引用
image_build_context 具名镜像上的 build_context
image_vars 具名镜像上的 build_vars
instance_type ctx.container.start() 中的 instance 选项。请参阅实例规格变更
max_instances 不支持。正在运行的实例会计入账户限制。在应用代码中强制执行任何按应用上限
应用范围的镜像滚动发布 停止并启动每个 Container 的应用代码
observability 保留在 Wrangler 配置中,受 durable_object 限制约束
unsafe.configuration.experimental_flags 保留在 Wrangler 配置中
ssh 和 authorized_keys 保留在 Wrangler 配置中
放置约束、滚动发布设置、wrangler_ssh 和 trusted_user_ca_keys 替换应用不支持

完整字段兼容性列表请参阅 Wrangler 配置。

实例规格变更

使用 durable_object 策略时,你通过 ctx.container.start() 的 instance 选项设置实例规格,而不是 Wrangler 配置中的 instance_type。instance 接受 lite、standard-1、standard-2、standard-3 和 standard-4。如果你现有的应用使用以下某个 instance_type 值,请选择替换项:

  • dev:使用 lite。
  • standard:使用 standard-1。
  • basic:选择 lite 或 standard-1。自定义实例类型至少需要 1 个 vCPU,因此你无法用自定义实例复现 basic。

自定义实例对象在运行时使用 camel case。将 memory_mib 重命名为 memoryMib,将 disk_mb 重命名为 diskMb。请参阅在运行时选择实例规格。

迁移应用

  1. 添加新的 Durable Object 类和 Container 应用。

    你不能通过将现有应用的 scheduling_policy 更改为 durable_object 来迁移它,因为创建后无法更改调度策略。你也不能复用现有 Durable Object 类,因为每个 Durable Object 命名空间只附加到一个 Container 应用。

    改为将以下所有内容添加到 Wrangler 配置:

    • 一个新的基于 SQLite 的 Durable Object 类。
    • 新类的 Durable Object 绑定(binding)。
    • 一个新的 Container 条目,设置 "scheduling_policy": "durable_object"、不同的 name,以及将 class_name 设为新类。

    保持现有 Container 条目、Durable Object 类和绑定(binding)不变,以便你可以将流量路由回去。更改现有条目的 name 或 class_name 可能导致 Wrangler 创建新应用,而不是更新现有应用。

    以下示例使用 exports。如果 Worker 使用旧版 migrations 数组,请改为添加带有 new_sqlite_classes: ["DurableSandbox"] 的新迁移。

    {
        "name": "sandbox-worker",
        "main": "src/index.ts",
        "upload_source_maps": true,
        "compatibility_date": "2026-09-29",
        "containers": [
            // Existing application. Keep this entry unchanged.
            {
                "class_name": "Sandbox",
                "image": "./container/Dockerfile",
                "instance_type": "standard-2",
                "max_instances": 10,
            },
            // Replacement application.
            {
                "name": "sandbox-durable-object",
                "class_name": "DurableSandbox",
                "scheduling_policy": "durable_object",
                "images": {
                    "base": {
                        "dockerfile": "./container/Dockerfile",
                    },
                },
            },
        ],
        "durable_objects": {
            "bindings": [
                {
                    "name": "SANDBOX",
                    "class_name": "Sandbox",
                },
                {
                    "name": "DURABLE_SANDBOX",
                    "class_name": "DurableSandbox",
                },
            ],
        },
        "exports": {
            "Sandbox": {
                "type": "durable-object",
                "storage": "sqlite",
            },
            "DurableSandbox": {
                "type": "durable-object",
                "storage": "sqlite",
            },
        },
    }
    name = "sandbox-worker"
    main = "src/index.ts"
    upload_source_maps = true
    compatibility_date = "2026-09-29"
    
    [[containers]]
    class_name = "Sandbox"
    image = "./container/Dockerfile"
    instance_type = "standard-2"
    max_instances = 10
    
    [[containers]]
    name = "sandbox-durable-object"
    class_name = "DurableSandbox"
    scheduling_policy = "durable_object"
    
    [containers.images.base]
    dockerfile = "./container/Dockerfile"
    
    [[durable_objects.bindings]]
    name = "SANDBOX"
    class_name = "Sandbox"
    
    [[durable_objects.bindings]]
    name = "DURABLE_SANDBOX"
    class_name = "DurableSandbox"
    
    [exports.Sandbox]
    type = "durable-object"
    storage = "sqlite"
    
    [exports.DurableSandbox]
    type = "durable-object"
    storage = "sqlite"
  2. 将启动配置移入替换类。

    当替换 Durable Object 启动其 Container 时,选择镜像和实例规格:

    src/index.jsjs
    import { DurableObject } from "cloudflare:workers";
    
    export class DurableSandbox extends DurableObject {
    	startContainer() {
    		if (this.ctx.container.running) {
    			return;
    		}
    
    		this.ctx.container.start({
    			image: this.ctx.container.images.base,
    			instance: "standard-2",
    			// Match the existing application's outbound access.
    			enableInternet: true,
    		});
    	}
    }
    src/index.tsts
    import { DurableObject } from "cloudflare:workers";
    
    export class DurableSandbox extends DurableObject {
        startContainer() {
            if (this.ctx.container.running) {
                return;
            }
    
            this.ctx.container.start({
                image: this.ctx.container.images.base,
                instance: "standard-2",
                // Match the existing application's outbound access.
                enableInternet: true,
            });
        }
    }

    将其他受支持的启动设置(例如 env 和 entrypoint)移入同一调用。将 enableInternet 设置为与现有应用匹配。除非你设置 enableInternet = false,否则 Container 类允许出站 Internet 访问。

    ctx.container.start() 会在 Container 准备好接受请求之前返回。在向 Container 发送流量之前,请添加应用特定的就绪检查。

  3. 部署并验证替换应用。

    部署两个应用:

    npx wrangler deploy

    在不更改生产路由的情况下启动替换 Container,例如通过使用 DURABLE_SANDBOX 绑定(binding)的仅测试路由。确认镜像、实例规格、环境、入口点、网络访问和就绪行为与现有应用匹配。

  4. 将流量切换到替换命名空间。

    更新 Worker 路由逻辑,通过替换 Durable Object 绑定(binding)解析 Container ID。同一个名称在每个命名空间中会解析到不同的 Durable Object。替换命名空间中的 Durable Object 无法访问旧命名空间中的存储。

    按逻辑 Container 选择绑定(binding),而不是按请求。如果同一名称的请求可以到达两个绑定(binding),例如在基于百分比的推出或渐进式部署期间,则一个逻辑沙盒可能运行两个 Container,它们的状态可能会分叉。例如,记录每个沙盒使用的命名空间,并在路由时读取该记录:

    // isMigrated() is application code that reads a per-sandbox record.
    const binding = (await isMigrated(sandboxName))
        ? env.DURABLE_SANDBOX
        : env.SANDBOX;
    const sandbox = binding.getByName(sandboxName);

    如果 Durable Object 状态必须迁移,请在将其路由到替换命名空间之前完成每个沙盒的应用特定转移。

  5. 观察替换应用。

    在观察期内保留旧应用、类和绑定(binding)。要回滚,请再次将流量路由到旧的 Durable Object 绑定(binding)。

    切换后进行的写入会留在替换命名空间中。如果应用接受写入,请在回滚前规划如何协调这些数据。

  6. 删除旧的 Container 应用。

    回滚期结束后,从 Wrangler 配置中移除旧的 Container 条目,并从 Worker 代码中移除旧的路由路径。部署更新后的 Worker。在不再需要其存储数据之前,保留旧的 Durable Object 类和绑定(binding)。

    从 Wrangler 配置中移除条目不会删除现有 Container 应用。列出应用并复制旧应用 ID:

    npx wrangler containers list

    删除旧应用:

    npx wrangler containers delete <OLD_APPLICATION_ID>

    此命令会删除该应用及其容器实例。

    仅在不再需要其存储数据时删除旧的 Durable Object 类。删除 Durable Object 类会永久删除其命名空间和存储数据。适用的清理流程请参阅 Durable Object 类导出 或 Durable Object 类迁移(旧版)。

相关资源

这篇文档对您有帮助吗?