跳转到内容
搜索文档

Durable Object 类导出

最后更新 查看 MarkdownAgent 设置

Wrangler 配置文件 中的 exports 字段是管理 Durable Object 类 生命周期的声明式方式。您声明 Worker 导出的每个 Durable Object 类——及其是 live、deleted、renamed 还是 transferred——Cloudflare 会将您的声明与已为 Worker 配置的 namespace 进行协调。

本页涵盖如何:

exports 的工作原理

当您部署声明 exports 的 Worker 时,Cloudflare 比较三个真实来源:

  1. 您的代码 — Worker 实际导出的 Durable Object 类集合。
  2. 您的 exports 配置 — 您对每个类的声明。
  3. 已配置状态 — 此 Worker 已存在的 Durable Object namespace。

仅出现在代码中的类在 exports 中声明之前会被忽略;Cloudflare 不会隐式配置 namespace。其他不一致(例如 live 条目缺少代码中的类,或已配置 namespace 无匹配条目)会作为结构化错误显示,或在意图明确时由 Cloudflare 自动应用操作。

一个最小的 exports 块将每个 Durable Object 类声明为一个活动 (live) 条目:

{
	"durable_objects": {
		"bindings": [
			{
				"name": "MY_DURABLE_OBJECT",
				"class_name": "MyDurableObject",
			},
		],
	},
	"exports": {
		"MyDurableObject": {
			"type": "durable-object",
			"storage": "sqlite",
		},
	},
}
[[durable_objects.bindings]]
name = "MY_DURABLE_OBJECT"
class_name = "MyDurableObject"

[exports.MyDurableObject]
type = "durable-object"
storage = "sqlite"

要声明破坏性操作(删除、重命名或转移类),您需要将条目的 state 更改为墓碑 (tombstone) 变体。类名保持不变;该值告诉 Cloudflare 如何处理现有的命名空间。

操作 state 必需字段
定义新类(默认值) "created" (或省略) storage
删除类 "deleted" (无)
重命名类 "renamed" renamed_to
将类转移到另一个 Worker "transferred" transferred_to
接收来自另一个 Worker 的转移 "expecting-transfer" storage, transfer_from

本页的其余部分将详细介绍每种操作,并提供了完整架构的 exports 配置参考链接。

定义 Durable Object 类

要定义新的 Durable Object 类,请在 exports 中添加一个以该类名为键的条目,并将 storage 设置为 "sqlite"

  1. 将该类添加到您的 Worker 代码中并将其导出:

    src/index.tsts
    import { DurableObject } from "cloudflare:workers";
    
    export class MyDurableObject extends DurableObject {
      // ...
    }
  2. 为该类添加绑定(如果您的 Worker 需要通过 env 访问它)并在 exports 中声明该类:

    {
      "durable_objects": {
        "bindings": [
          {
            "name": "MY_DURABLE_OBJECT",
            "class_name": "MyDurableObject"
          }
        ]
      },
      "exports": {
        "MyDurableObject": {
          "type": "durable-object",
          "storage": "sqlite"
        }
      }
    }
    [[durable_objects.bindings]]
    name = "MY_DURABLE_OBJECT"
    class_name = "MyDurableObject"
    
    [exports.MyDurableObject]
    type = "durable-object"
    storage = "sqlite"
  3. 部署 Worker:

    npx wrangler deploy

在您首次部署时,Cloudflare 会为该类预配命名空间。在后续使用相同条目进行的部署中,不会对命名空间进行任何更改——该条目仅确认该类仍然处于活动 (live) 状态。

删除 Durable Object 类

使用 deleted 墓碑 (tombstone) 替换活动 (live) 条目以停用 Durable Object 类。删除类会永久删除其命名空间及其所有存储的数据——这不是软删除。

  1. 从您的 Worker 代码中移除该类。

  2. durable_objects.bindings 中移除该类的绑定。

  3. 将该类在 exports 中的条目更改为 deleted 墓碑 (tombstone):

    {
      "exports": {
        "OldDurableObject": {
          "type": "durable-object",
          "state": "deleted"
        }
      }
    }
    [exports.OldDurableObject]
    type = "durable-object"
    state = "deleted"
  4. 部署 Worker:

    npx wrangler deploy

在部署时,deleted 墓碑 (tombstone) 强制满足两个先决条件:

  • 类不能存在于您的 Worker 代码中。Cloudflare 不会删除其类仍在随代码交付的命名空间,因为运行时绑定会解析到已删除的命名空间。
  • 您账户中的其他 Worker 都不能绑定到该命名空间。如果另一个 Worker 仍然绑定到该类,部署将被拒绝,并显示 tombstone_delete_blocked_by_external_bindings 错误,同时返回引用脚本的列表。请先重新部署这些不带绑定的 Worker,然后重新运行部署。

一旦命名空间被删除,墓碑 (tombstone) 就会失效。Cloudflare 会在协调 (reconciliation) 输出中对此进行报告,并在 removable_entries 中列出该条目,以便您可以安全地将其从 exports 中移除。

重命名 Durable Object 类

重命名 Durable Object 类会将存储的数据在同一个 Worker 内从一个类移至另一个类。重命名需要:

  • 一个以旧类名为键的 renamed 墓碑 (tombstone),其 renamed_to 指向新类名。
  • 在同一个 exports 映射中为新类名提供一个活动 (live) 条目(以便数据有目的地)。

对于旧类不再存在于代码中的全新部署,只需一次部署即可:

{
	"exports": {
		"OldName": {
			"type": "durable-object",
			"state": "renamed",
			"renamed_to": "NewName"
		},
		"NewName": {
			"type": "durable-object",
			"storage": "sqlite"
		}
	}
}
[exports.OldName]
type = "durable-object"
state = "renamed"
renamed_to = "NewName"

[exports.NewName]
type = "durable-object"
storage = "sqlite"

在重命名生效后,命名空间的类名将更新为 NewName,并且引用新类名的运行时绑定将解析为相同的数据。

避免重命名期间的停机时间

重命名 Durable Object 类涉及两处更新,这两处更新在运行时层并非完全原子化:命名空间的类指针和导出该类的 Worker 代码。在部署逐步发布期间,其中一个更新可能会比另一个提前几秒钟可见。为了避免在此窗口期间出现运行时错误,请使用三次部署重命名流程

  1. 将新名称别名化为旧类。 将新类名作为规范类添加到代码中,并以旧名称重新导出它,以便现有实例能够继续解析:

    src/index.tsts
    import { DurableObject } from "cloudflare:workers";
    
    export class NewName extends DurableObject {
      // ...
    }
    export { NewName as OldName };

    保持 exports 不变。执行部署。

  2. 在别名仍保留时应用重命名。 更新 exports 以添加 renamed 墓碑 (tombstone) 和新的活动 (live) 条目:

    {
      "exports": {
        "OldName": {
          "type": "durable-object",
          "state": "renamed",
          "renamed_to": "NewName"
        },
        "NewName": {
          "type": "durable-object",
          "storage": "sqlite"
        }
      }
    }
    [exports.OldName]
    type = "durable-object"
    state = "renamed"
    renamed_to = "NewName"
    
    [exports.NewName]
    type = "durable-object"
    storage = "sqlite"

    执行部署。Cloudflare 将应用重命名并显示 tombstone_class_still_in_code 信息通知——这是符合预期的,并证实了这种安全的发布模式。

  3. 移除别名。 上一次部署完全发布后,从代码中移除 OldName 别名:

    src/index.tsts
    import { DurableObject } from "cloudflare:workers";
    
    export class NewName extends DurableObject {
      // ...
    }

    保持 exports 不变。执行部署。OldName 墓碑 (tombstone) 现在已失效,Cloudflare 将其列在 removable_entries 中——您可以在下一次修改配置时将该条目从 exports 中删除。

renamed_to 目标必须满足以下条件:

  • 必须是有效的 JavaScript 标识符,且与源类名不同。
  • 在同一个 exports 映射中显示为活动 (live) 条目(state: "created" 或省略)。如果 renamed_to 的值命名了另一个墓碑或完全缺失,Cloudflare 将予以拒绝。
  • 不能与此 Worker 上同名的现有命名空间发生冲突。如果目标名称下已存在命名空间,请先在之前的部署中通过其自身的 deleted 墓碑 (tombstone) 将其删除。

在 Worker 之间转移 Durable Object 类

转移 (Transferring) 会将现有的 Durable Object 命名空间从同一个账户中的一个 Worker()移至另一个 Worker(目标)。由于需要两个 Worker 进行协调,因此转移是一个多次部署流程。

目标 Worker 声明一个命名源 Worker 的 expecting-transfer 条目。源 Worker 声明一个命名目标 Worker 的 transferred 墓碑 (tombstone)。当源 Worker 的部署完成时,将提交实际的交接。

推荐的流程包含四次部署:

  1. 源 Worker——初始状态。 源将 MyDO 声明为活动 (live) 类。其他什么都还没变。

    {
      "exports": {
        "MyDO": { "type": "durable-object", "storage": "sqlite" }
      }
    }
    [exports.MyDO]
    type = "durable-object"
    storage = "sqlite"
  2. 目标 Worker——接收转移。 目标将 MyDO 添加到其代码中,并声明一个命名源 Worker 的 expecting-transfer 条目。此时不要在目标上为 MyDO 添加 durable_objects.bindings 条目——在此阶段,Cloudflare 不会通过源的命名空间来路由自引用绑定。

    {
      "exports": {
        "MyDO": {
          "type": "durable-object",
          "state": "expecting-transfer",
          "storage": "sqlite",
          "transfer_from": "source-worker"
        }
      }
    }
    [exports.MyDO]
    type = "durable-object"
    state = "expecting-transfer"
    storage = "sqlite"
    transfer_from = "source-worker"

    部署目标。Cloudflare 会记录一个待处理的转移,并在协调 (reconciliation) 输出中发出 Transfer pending 通知。

  3. 源 Worker——提交转移。 将源的 MyDO 条目更改为命名目标 Worker 的 transferred 墓碑 (tombstone)。暂时将该类保留在源头代码中:

    {
      "exports": {
        "MyDO": {
          "type": "durable-object",
          "state": "transferred",
          "transferred_to": "target-worker"
        }
      }
    }
    [exports.MyDO]
    type = "durable-object"
    state = "transferred"
    transferred_to = "target-worker"

    部署源。Cloudflare 会匹配待处理的转移,并自动将命名空间重新分配给目标 Worker。协调 (reconciliation) 输出会报告 Transferred (committed): MyDO → target-worker

    如果在提交转移后源 Worker 仍需要访问 MyDO,请更新其 durable_objects.bindings 条目,使其通过 script_name 指向目标 Worker:

    {
      "durable_objects": {
        "bindings": [
          {
            "name": "MY_DURABLE_OBJECT",
            "class_name": "MyDO",
            "script_name": "target-worker"
          }
        ]
      }
    }
    [[durable_objects.bindings]]
    name = "MY_DURABLE_OBJECT"
    class_name = "MyDO"
    script_name = "target-worker"

    如果源 Worker 不再需要访问 MyDO,请在从源 Worker 的代码中移除 MyDO 时一并移除该绑定。

  4. 目标 Worker——绑定类。 一旦源的部署完全发布,请使用针对 MyDOdurable_objects.bindings 条目重新部署目标。此时,该绑定将解析为目标 Worker 上的命名空间。

    {
      "durable_objects": {
        "bindings": [
          {
            "name": "MY_DURABLE_OBJECT",
            "class_name": "MyDO"
          }
        ]
      },
      "exports": {
        "MyDO": { "type": "durable-object", "storage": "sqlite" }
      }
    }
    [[durable_objects.bindings]]
    name = "MY_DURABLE_OBJECT"
    class_name = "MyDO"
    
    [exports.MyDO]
    type = "durable-object"
    storage = "sqlite"

在交接在所有地方都发布完毕后,您可以从源 Worker 的代码中移除 MyDO,并从源的 exports 映射中删除 transferred 墓碑 (tombstone)。如果该账户中的其他 Worker 仍绑定到源上的 MyDO,协调 (reconciliation) 输出会将其列在 referencing_scripts 中;在移除源墓碑 (tombstone) 之前,请重新部署这些 Worker,并将其绑定重新指向目标。

取消待处理的转移

待处理的转移会一直存在,直到源 Worker 提交包含 transferred 墓碑 (tombstone) 的部署,或者目标 Worker 通过移除 expecting-transfer 条目来取消它。要取消转移,请重新部署不包含该条目的目标(或将其替换为正常的活动 (live) 条目)。Cloudflare 会删除待处理记录,且源 Worker 将保留其命名空间。

转移限制

  • 两个 Worker 必须位于同一个 Cloudflare 账户中。
  • 不支持跨 dispatch-namespace 的转移。源 Worker 和目标 Worker 必须处于相同的 dispatch-namespace 上下文中(或两者都不在任何 dispatch-namespace 中)。
  • 目标 Worker 每次只能为每个类保留一个待处理的阶段 1 (phase-1) 提示。要将待处理的转移重定向到不同的源,请先取消当前待处理的转移。

存储后端

活动 (live) 条目(state: "created"state: "expecting-transfer")必须声明 storage 值:

  • "sqlite" 选择 SQLite 存储后端。这是推荐的且针对新命名空间的唯一路径。基于 SQLite 的命名空间支持 SQL时间点恢复 (Point-in-Time Recovery) 以及更高的单个对象存储限制。
  • "legacy-kv" 选择键值 (key-value) 存储后端。Cloudflare 仅接受此值用于已预配了键值存储的命名空间(通常是那些在 SQLite 成为默认后端之前,使用旧版 migrations 数组启动的 Worker)。您无法通过 exports 创建的基于键值存储的命名空间。

一旦命名空间存在,存储类型就不可更改。如果 exports 更改将已预配的命名空间从 sqlite 切换到 legacy-kv(或反之),Cloudflare 将拒绝该更改并显示 storage_type_mismatch 错误。要真正更改存储后端,必须先通过 deleted 墓碑 (tombstone) 删除命名空间,然后在新后端下重新预配(在此期间数据会完全丢失)。

读取协调输出

当部署应用 Durable Object 类生命周期更改时,wrangler deploy 将打印 Durable Object exports reconciliation 块。当协调 (reconciliation) 产生警告、信息通知或可移除条目时,该块也会出现。当没有任何变化且没有通知时,Wrangler 会省略此块。

典型的输出如下所示:

Durable Object exports reconciliation:
  Created: ChatRoom
  Renamed: OldRoom → ChatRoom
  Transferred (committed): Widget → target-worker
  Transfer pending: Incoming ← source-worker

  Info:
    [tombstone_class_still_in_code] OldRoom: Tombstone of type 'renamed' applied. Class 'OldRoom' is still exported in code; this is the supported pattern for zero-downtime rename rollouts.
    [stale_tombstone] OldGone: Tombstone of type 'deleted' for class 'OldGone' has no effect (no namespace exists with this class name). Safe to remove from `exports`.

  Safe to remove from `exports`: OldGone

该输出块有四个部分:

  • 操作行 (Action lines) (Created, Updated, Deleted, Renamed, Transferred, Transfer pending) 报告 Cloudflare 在此部署期间应用的更改。
  • 警告 (Warnings)(黄色)标记应进行调查但不妨碍部署的情况。警告方案集保留供将来使用;当前的 Cloudflare 部署不会发出它们。
  • 信息 (Info)(置灰)报告非阻塞通知:不再适用的失效墓碑 (tombstone),以及在源类仍在代码中时应用的墓碑(支持零停机时间发布的推荐模式)。
  • 可以安全地从 exports 中移除 (Safe to remove from exports) 列出了已失效且账户中没有其他 Worker 绑定到源类的墓碑 (tombstone) 条目。您可以在下一次修改配置时从 exports 映射中删除这些条目。

信息条目可以包含 referencing_scripts 列表——账户中其绑定仍然解析为受影响命名空间的其他 Worker。在移除墓碑 (tombstone) 之前,请重新部署这些 Worker,并将绑定重新指向新类名,否则它们的绑定将被遗孤 (orphan)。

If the deploy fails, the output shows a structured error per class:

✘ [orphaned_provisioned_namespace] class 'Bar': A namespace exists for 'Bar' but no `exports` entry declares it.
    Suggestion: add an `exports` entry for 'Bar', or add a `deleted` tombstone to remove the namespace.
    Referencing scripts: worker-foo, worker-bar

单次部署中的所有类级别错误都将统一报告,以便您一次性解决。有关所有错误场景的完整列表,请参阅错误参考

失效的墓碑与清理

当应用墓碑 (tombstone) 不产生状态更改时,它就会变得失效 (stale)——例如,针对其命名空间已被移除的类的 deleted 墓碑,或者重命名已经生效后的 renamed 墓碑。

在每次存在失效墓碑的部署中,Cloudflare 都会发出 stale_tombstone 信息通知,直到您从 exports 中移除该条目。该通知会故意重复出现,以免您忘记清理。

对于重命名和已转移的墓碑 (tombstone),Cloudflare 还会列出您账户中的其他 Worker,它们的 durable_objects.bindings 条目仍然引用源类名。这些会作为 referencing_scripts 显示在信息通知上。当 referencing_scripts 不为空时,移除墓碑可能会使这些绑定遗孤——请先重新部署引用的 Worker,将其绑定重新指向新类。

协调 (reconciliation) 输出中顶层的“Safe to remove from exports”行会命名每个 referencing_scripts 为空的失效墓碑 (tombstone)。请将该列表作为“您现在可以删除这些”的权威提示。

环境、分发命名空间和预览

可以在 Wrangler 配置文件顶层指定 exports,并针对每个环境 (environment) 进行重写:

{
	// top-level exports apply to the default environment
	"exports": {
		"MyDO": { "type": "durable-object", "storage": "sqlite" }
	},
	"env": {
		"staging": {
			// override for the staging environment
			"exports": {
				"MyDO": { "type": "durable-object", "storage": "sqlite" }
			}
		}
	}
}
[exports.MyDO]
type = "durable-object"
storage = "sqlite"

[env.staging.exports.MyDO]
type = "durable-object"
storage = "sqlite"

如果仅在顶层声明了 exports,则命名的环境会继承相同的值。每个环境维护自己预配的命名空间,因此墓碑 (tombstone) 仅在声明它们的环境中生效。

预览部署 (Preview deployments)分发命名空间 (dispatch namespaces) 遵循相同的规则。不支持跨分发命名空间的转移——在 transferred / expecting-transfer 配对中的源 Worker 和目标 Worker 必须同时存在于相同的分发命名空间上下文中(或同时在任何分发命名空间之外)。

exports 配置参考

exports 字段是一个以 Durable Object 类名为键的映射。每个值都是一个对象,其字段取决于 state

  • type stringrequired

    • 对于 Durable Object 类条目,请将其设置为 "durable-object"
  • state stringoptional

    • 生命周期状态。为以下值之一:"created"(默认值,若要使用可省略)、"deleted""renamed""transferred""expecting-transfer"
  • storage stringconditional

    • state"created""expecting-transfer" 时必填。为以下值之一:"sqlite"(推荐,新命名空间的唯一有效值)或 "legacy-kv"(仅用于现有的基于键值存储的命名空间)。在墓碑 (tombstone) 状态下禁用。
  • renamed_to stringconditional

    • state"renamed" 时必填。目标类名。必须是有效的 JavaScript 标识符,与源类名不同,并且在同一个 exports 映射中作为活动 (live) 条目出现。
  • transferred_to stringconditional

    • state"transferred" 时必填。将接收命名空间的目标 Worker 的名称。
  • transfer_from stringconditional

    • state"expecting-transfer" 时必填。命名空间所转移自的源 Worker 的名称。

下表列出了每个 state 允许和禁用的字段:

state 必需 禁用
"created" (默认) storage renamed_to, transferred_to, transfer_from
"deleted" (无) storage, renamed_to, transferred_to, transfer_from
"renamed" renamed_to storage, transferred_to, transfer_from
"transferred" transferred_to storage, renamed_to, transfer_from
"expecting-transfer" storage, transfer_from renamed_to, transferred_to

错误参考

当部署未能通过协调 (reconciliation) 时,Cloudflare 将为每个类返回一个错误,并附带结构化的 scenario 标签、人类可读的消息,以及(在适用时)suggestion(建议)和 referencing_scripts 列表:

场景 (Scenario) 含义 如何修复
provisioned_class_missing_from_config 某个类存在已预配的命名空间,且 Worker 代码仍在导出该类,但 exports 中没有该类的条目。 添加一个活动 (live) 条目(state: "created")以保留该命名空间,或者添加一个墓碑 (tombstone)(deletedrenamedtransferred)以停用它。
config_export_not_in_code 活动 (live) 条目声明了 Worker 代码未导出的类。 将该类添加到您的代码中,或者用墓碑 (tombstone) 替换该条目。
config_references_nonexistent_class 活动 (live) 条目声明了一个既不在代码中也未预配的类。 移除该条目,或者将该类添加到您的 Worker 代码中。
orphaned_provisioned_namespace 某个类存在已预配的命名空间,但该类既不在代码中也没有被声明。 为该类添加一个墓碑 (tombstone),或者将该类重新添加至代码和 exports 中。
invalid_export exports 条目的结构无效——例如,为新命名空间请求 legacy-kv,或者一个类映射到多个已预配的命名空间。 纠正该条目:对于新命名空间使用 "storage": "sqlite",或者使用 deletedrenamed 墓碑 (tombstone) 解决重复问题。
tombstone_delete_class_still_in_code deleted 墓碑 (tombstone) 命名的类仍在代码中被导出。 先从代码中移除该类,然后再部署墓碑 (tombstone)。
tombstone_delete_blocked_by_external_bindings 账户中的另一个 Worker 绑定到了正在被删除的命名空间。 重新部署不带该绑定的引用 Worker,然后重新运行您的部署。
tombstone_renamed_to_occupied renamed_to 目标与同名的现有命名空间冲突。 在先前的部署中,通过该冲突命名空间自身的 deleted 墓碑 (tombstone) 将其删除。
transferred_pending_not_found transferred 墓碑 (tombstone) 在目标 Worker 上没有匹配的 expecting-transfer 条目。 先部署目标 Worker,并声明命名该源 Worker 的 expecting-transfer 条目。
transferred_target_missing transferred_to 命名的目标 Worker 不再存在。 transferred_to 更新为有效的目标,或者移除该墓碑 (tombstone)。
transferred_target_mismatch transferred_to 的值与待处理转移记录的目标不匹配。 transferred_to 设置为待处理转移的目标,或者让目标在重定向之前取消其 expecting-transfer 条目。
transferred_source_in_dispatch_namespace 声明 transferred 墓碑 (tombstone) 的源 Worker 处于分发命名空间 (dispatch namespace) 中;不支持跨分发命名空间转移。 在单个分发命名空间上下文中执行转移。
transferred_target_in_dispatch_namespace transferred 墓碑 (tombstone) 的目标处于分发命名空间 (dispatch namespace) 中;不支持跨分发命名空间转移。 让目标重新部署且不包含 expecting-transfer 以取消待处理的转移,或者让两个 Worker 保持在相同的上下文中。
phase_one_transfer_after_commit_mismatch 目标的命名空间转移自与声明不符的源。 移除 expecting-transfer 条目——在提交后,转移无法被重定向。
phase_one_transfer_target_class_provisioned 目标 Worker 已经拥有该类的命名空间。 用正常的活动 (live) 条目替换 expecting-transfer 条目,或者先删除现有的命名空间。
phase_one_transfer_duplicate 针对相同类的另一个 expecting-transfer 提示已经在进行中。 先通过移除或替换其条目来取消现有的待处理转移。
phase_one_transfer_source_missing transfer_from 命名的源 Worker 不存在于该账户中。 纠正源 Worker 的名称。
phase_one_transfer_source_namespace_missing 源 Worker 没有该类的命名空间。 确保在目标声明 expecting-transfer 之前,源 Worker 已经部署了该类。
phase_one_transfer_source_in_dispatch_namespace 源 Worker 处于分发命名空间 (dispatch namespace) 中;不支持跨分发命名空间转移。 将转移移至单个分发命名空间上下文中进行。
phase_one_transfer_target_in_dispatch_namespace 目标 Worker 处于分发命名空间 (dispatch namespace) 中;不支持跨分发命名空间转移。 将转移移至单个分发命名空间上下文中进行。
storage_type_mismatch 声明的 storage 值与预配命名空间的存储后端不匹配。 存储后端无法就地更改。如果您确实需要切换,请删除该命名空间并在新后端下重新预配。
free_tier_requires_sqlite 账户的计划仅支持基于 SQLite 的命名空间,但该条目请求了 legacy-kv 使用 "storage": "sqlite"

约束与限制

  • exportsmigrations 互斥。 包含这两个字段的 Worker 配置将在验证时被拒绝。一旦使用 exports 部署了 Worker,后续部署必须继续使用 exports(或者两者都不使用,这会针对空配置进行协调,通常是一个错误)。
  • wrangler versions upload 不会应用生命周期更改。 就像旧版 migrations 数组一样,Durable Object 生命周期更改只能通过 wrangler deploy 应用。如果您的 Wrangler 配置包含 exports 条目,wrangler versions upload 会快速失败并报错。请参阅部署管理 - Durable Object 迁移
  • exports 不支持渐进式部署。 生命周期更改在 Cloudflare 控制平面是原子性的,无法渐进式地推出。请参阅具有 Durable Objects 的渐进式部署 - Durable Object 类生命周期更改
  • 回滚无法跨越生命周期更改。 您无法回滚到在由 exports 驱动的生命周期更改之前部署的版本。请参阅回滚 - 绑定
  • 存储后端一旦预配即不可变。 您不能就地更改命名空间的 storage 值;请进行删除并重新预配。

从旧版 migrations 流程迁移

使用 migrations 数组的现有 Worker 可以转而使用 exports,无需进行任何数据迁移。已预配的命名空间将保持原样;仅配置的形式发生变化。

要确定类现有的存储后端,请追溯到最初创建该类的迁移。通过 new_sqlite_classes 引入的类使用 sqlite,而通过 new_classes 引入的类使用 legacy-kv

  1. 确定您的 Worker 当前导出的活动 (live) Durable Object 类。每个具有活动命名空间的类都会成为一个活动的 exports 条目。
  2. migrations 数组替换为 exports 映射。对于每个现有类,添加一个以该类名为键的条目,且包含 "type": "durable-object"。使用 "storage": "sqlite""storage": "legacy-kv" 与现有的存储后端相匹配。
  3. 从配置中移除 migrations 数组。
  4. 部署。

对比来看,典型 migrations 历史记录的等价转换是:

{
	"migrations": [
		{ "tag": "v1", "new_sqlite_classes": ["ChatRoom"] }
	]
}
[[migrations]]
tag = "v1"
new_sqlite_classes = [ "ChatRoom" ]
{
	"exports": {
		"ChatRoom": { "type": "durable-object", "storage": "sqlite" }
	}
}
[exports.ChatRoom]
type = "durable-object"
storage = "sqlite"

未来的生命周期更改(删除、重命名、转移)完全通过 exports 进行——没有与 tag 字段等价的项,也无需保留历史条目。exports 映射的当前状态就是唯一真实来源。

这篇文档对您有帮助吗?