Cloudflare Durable Objects 配置实战指南:wrangler.jsonc 绑定、数据本地化与迁移机制全解
【免费下载链接】skillsSkills Catalog for Codex项目地址: https://gitcode.com/GitHub_Trending/skills4/skills
本指南以本仓库 cloudflare-deploy skill 中的 Durable Objects 配置文档 为核心骨架,结合同目录下的 README、API、Patterns、Gotchas 以及 DO Storage 文档 纵深展开。读完本文,你将掌握:如何在wrangler.jsonc中正确声明 Durable Object 绑定与迁移、如何通过 Binding Options 访问其他 Worker 中的 DO、如何利用 Jurisdiction 满足欧盟数据驻留与 FedRAMP 合规、如何为 staging/production 隔离命名空间,以及npx wrangler durable-objects系列管理命令的完整用法。
一、Durable Objects 是什么:为什么需要一份专门的配置文档
Durable Objects(DO)将「计算」与「存储」打包成全局唯一、强一致的单元:每个 DO 实例拥有全局唯一 ID、与计算同地的强一致存储、自动就近放置、内存态加持久化存储的双层状态,并且以单线程方式串行处理请求(天然无竞态)。它正是构建状态协调、实时协同、计数、会话、限流等有状态应用的平台基座。
正因为 DO 是有状态的,它的声明与配置远不止一个main入口那么简单:你需要在wrangler.jsonc中完成绑定声明、迁移策略、环境隔离、计算限额等一整套配置。本文讨论的 configuration.md 正是这套配置的完整权威说明,下面逐节展开。
二、基本配置:在 wrangler.jsonc 中声明 Durable Object
DO 的配置入口是 Worker 项目根目录下的wrangler.jsonc(或wrangler.toml)。核心配置项包括顶层durable_objects与migrations两个块,完整示例如下:
{ "name": "my-worker", "main": "src/index.ts", "compatibility_date": "2025-01-01", // Use latest; ≥2024-04-03 for RPC "durable_objects": { "bindings": [ { "name": "MY_DO", // Env binding name "class_name": "MyDO" // Class exported from this worker }, { "name": "EXTERNAL", // Access DO from another worker "class_name": "ExternalDO", "script_name": "other-worker" } ] }, "migrations": [ { "tag": "v1", "new_sqlite_classes": ["MyDO"] } // Prefer SQLite ] }逐项拆解:
name/main:Worker 名称与入口文件,与普通 Worker 配置一致。compatibility_date:建议始终使用最新日期。特别地,若要在 Worker 侧以 RPC 方式直调 DO 方法(而不是走fetch()),compatibility_date必须≥ 2024-04-03,否则 RPC 不可用,只能退回fetch()调用(见下文「RPC 与 fetch() 的选择」)。durable_objects.bindings:数组,每项声明一个绑定。name是注入env的绑定名(如env.MY_DO),class_name是该 Worker 内导出的 DO 类名。示例中第二个绑定通过script_name指向另一个 Worker(other-worker)导出的ExternalDO类,实现跨 Worker 访问。migrations:声明 DO 类如何随版本演进(创建、重命名、迁移、删除)。注意其中new_sqlite_classes明确标记了「优先使用 SQLite 后端」,这是当前官方推荐的存储选择。
存储后端的选择:SQLite 与 KV 的取舍
new_sqlite_classes与new_classes分别对应两种 DO 存储后端,差异见 DO Storage 概览:
| 后端 | 创建方式 | 可用 API | 30 天时间点恢复(PITR) |
|---|---|---|---|
| SQLite(推荐) | new_sqlite_classes | SQL + 同步 KV + 异步 KV | ✅ |
| KV(遗留) | new_classes | 仅异步 KV | ❌ |
从源码结构看,DO Storage 文档 将 SQLite 定位为推荐后端:它支持结构化数据、关系查询与事务,单实例存储上限 10GB;而 KV 后端只能使用异步 KV API,也不支持时间点恢复。因此新项目一律使用new_sqlite_classes。
三、Binding Options:绑定项的完整参数
单个绑定项的完整可配置字段如下:
{ "name": "BINDING_NAME", "class_name": "ClassName", "script_name": "other-worker", // Optional: external DO "environment": "production" // Optional: isolate by env }name:注入env的绑定标识符,Worker 代码中通过env.<name>拿到DurableObjectNamespace。class_name:实际处理逻辑的 DO 类名,必须与源码中export class导出的类名一致。script_name:可选。省略时表示 DO 类由当前 Worker 导出;填写另一个 Worker 名称时,当前 Worker 可以访问那个 Worker 导出的 DO 类(即「外部 DO」),用于跨服务共享有状态协调单元。environment:可选。配合env块做环境隔离时使用,让同一绑定在不同环境(staging/production)指向相互独立的对象命名空间(详见第六节)。
四、Jurisdiction(数据本地化):从 ID 创建那一刻锁定数据边界
对于 GDPR、FedRAMP 等合规要求,DO 支持在「创建 ID」时指定司法辖区(jurisdiction),从而保证该 DO 实例的物理位置、存储与计算全部落在指定边界内。核心示例:
// EU data residency const id = env.MY_DO.idFromName("user:123", { jurisdiction: "eu" }) // Available jurisdictions const jurisdictions = ["eu", "fedramp"] // More may be added // All operations on this DO stay within jurisdiction const stub = env.MY_DO.get(id) await stub.someMethod() // Data stays in EU关键要点(务必牢记):
- 在 ID 创建时设置,创建后不可变更:
jurisdiction是 ID 的属性,idFromName/newUniqueId一旦返回 ID,其辖区即已固定,之后无法修改。如果后续需要迁辖区,只能换用新 ID 重建。 - 物理位置保证:DO 实例的物理部署位置、存储与计算均被限定在指定辖区边界内。
- 强隔离语义:不存在跨辖区访问——如果请求访问的 DO 位于不同辖区,调用会直接失败。因此设计时必须确保创建 ID 与访问 ID 的代码使用一致的 jurisdiction 参数。
从 README 的 ID 生成策略看,三种 ID 生成方式各有定位:idFromName()生成确定性 ID,适合命名协调(限流、分布式锁);newUniqueId()生成随机 ID,适合分片高吞吐负载;idFromString()则从既有 ID 字符串反推 ID 对象。Jurisdiction 选项可以叠加在这三种方式之上使用。
五、Migrations:DO 类随版本演进的生命周期管理
DO 类的增删改不能只改代码,必须通过migrations显式声明,否则部署时 Wrangler 无法知道如何处理既有实例。完整示例:
{ "migrations": [ { "tag": "v1", "new_sqlite_classes": ["MyDO"] }, // Create SQLite (recommended) // { "tag": "v1", "new_classes": ["MyDO"] }, // Create KV (paid only) { "tag": "v2", "renamed_classes": [{ "from": "Old", "to": "New" }] }, { "tag": "v3", "transferred_classes": [{ "from": "Src", "from_script": "old", "to": "Dest" }] }, { "tag": "v4", "deleted_classes": ["Obsolete"] } // Destroys ALL data! ] }每种迁移动作的语义:
new_sqlite_classes:新建使用 SQLite 后端的 DO 类(推荐)。new_classes:新建使用 KV 后端的 DO 类,注意该操作仅限付费账户。renamed_classes:将旧类Old重命名为New,实例与数据随类名迁移。transferred_classes:把类Src(可指定其来源脚本from_script)迁移到目标类Dest,适合跨脚本/跨类转移数据而无需删除。deleted_classes:删除类。⚠️立即销毁该类的所有 DO 实例与全部数据,不可逆!若只是转移而非清除,应使用transferred_classes。
迁移规则(违反即部署失败):
- tag 必须唯一且严格递增:
v1, v2, v3...依次排列,不允许跳号或重复。这也是 gotchas.md 中「Migration Failed (Deploy error)」最常见的原因。 - 不支持回滚:一旦部署应用了迁移,无法回退。上线前务必用
npx wrangler deploy --dry-run验证迁移合法性。 - 部署时自动应用:
npx wrangler deploy会先检查 migrations 数组,把未应用的新条目按顺序应用到线上。 - 优先
new_sqlite_classes:除非有明确理由,新类一律走 SQLite;new_classes仅限付费账户且失去 PITR 能力。 deleted_classes立即且不可逆地销毁全部数据:需要保留数据的任何移动都优先考虑renamed_classes/transferred_classes。
从 DO Storage 文档 可知,SQLite 后端还附带 30 天时间点恢复(PITR)能力,可作为高风险迁移前的「后悔药」——不过它只恢复存储数据,不撤销迁移元数据,因此核心防线仍然是--dry-run预检。
六、环境隔离:为 staging/production 建立独立的 DO 命名空间
DO 实例天然与「绑定 + 环境」绑定。如果你在 staging 与 production 共用同一绑定,二者会读到同一批 DO 实例,这在有状态应用中是不可接受的。正确做法是借助env块为每个环境覆盖durable_objects配置:
{ "durable_objects": { "bindings": [{ "name": "MY_DO", "class_name": "MyDO" }] }, "env": { "production": { "durable_objects": { "bindings": [ { "name": "MY_DO", "class_name": "MyDO", "environment": "production" } ] } } } }要点:
- 顶层
durable_objects是默认(本地开发/未指定环境时)的绑定声明。 env.production块内的绑定额外指定了"environment": "production"。该字段将 DO 类放入独立的命名空间,从而让生产环境的 DO 实例与 staging/默认环境的实例完全隔离——两边的对象互不可见、数据互不干扰。- 部署到该环境使用:
npx wrangler deploy --env production。
这也印证了第三节的environment字段用途:它是「环境隔离」的开关,配合env配置块实现按环境分命名空间。
七、Limits & Settings:调整 CPU 时间上限
DO 单次请求默认有 30 秒 CPU 时间限制,超限会被终止。可通过limits.cpu_ms调高:
{ "limits": { "cpu_ms": 300000 // Max CPU time: 30s default, 300s max } }- 默认值:30 秒(30000 ms)。
- 最大值:300 秒(300000 ms),即示例中的取值。
- 适用场景:确需长时间计算的任务;对于超长任务,更稳妥的策略是切分工作并使用 Alarm 分片处理,而不是一味调高上限。
完整限制表见 gotchas.md,其中与配置直接相关的关键限额包括:
| 限额项 | Free / Paid | 说明 |
|---|---|---|
| 单 DO SQLite 存储 | 10 GB | 按实例计 |
| SQLite 总存储 | 5 GB / 不限 | 账户级配额 |
| 单 KV 键值大小 | 2 MB | SQLite/异步 KV 均适用 |
| CPU 时间(默认/最大) | 30s / 300s | 通过limits.cpu_ms设置 |
| DO 类数量 | 100 / 500 | 不同的 DO 类定义数 |
| 单表 SQL 列数 | 100 | 每表 |
| SQL 语句大小 | 100 KB | 单条查询上限 |
| WebSocket 消息大小 | 32 MiB | 单条消息 |
| 单 DO 吞吐 | ~1K req/s | 软限制,超出需分片 |
| 单 DO Alarm 数 | 1 | 多事件需队列模式 |
| 单 DO 内存 | 128 MB | 内存态 + WebSocket 缓冲 |
八、TypeScript 类型:DurableObjectNamespace 的正确用法
配置完成后,代码侧需要类型化的绑定声明。推荐写法:
import { DurableObject } from "cloudflare:workers"; interface Env { MY_DO: DurableObjectNamespace<MyDO>; } export class MyDO extends DurableObject<Env> {} type DurableObjectNamespace<T> = { newUniqueId(options?: { jurisdiction?: string }): DurableObjectId; idFromName(name: string): DurableObjectId; idFromString(id: string): DurableObjectId; get(id: DurableObjectId): DurableObjectStub<T>; };要点:
- DO 类继承自
cloudflare:workers导出的DurableObject<Env>基类;构造函数接收DurableObjectState(封装 storage、WebSockets、alarms)与Env(各绑定)。 DurableObjectNamespace<T>是env.MY_DO的类型:newUniqueId生成随机 ID(可携带jurisdiction选项),idFromName生成确定性 ID,idFromString从字符串还原 ID,get(id)返回指向该实例的DurableObjectStub<T>,随后即可直调类上导出的 RPC 方法。- 从 api.md 可见,DO 类内部可同时实现 RPC 方法(Worker 直接调用)、
fetch()处理器(HTTP 语义/代理/遗留兼容)以及生命周期处理器(alarm、webSocketMessage、webSocketClose、webSocketError)。
RPC 与 fetch() 的选择(配置层面的连带决策)
选择调用方式与compatibility_date直接相关:
- RPC(推荐,新项目):要求
compatibility_date ≥ 2024-04-03。类型安全、写法更简单:const count = await stub.increment()。 - fetch()(遗留/特殊场景):需要 HTTP 语义(读写 header、状态码)、需要把请求代理转发给 DO、或需要兼容旧项目时使用:
const count = await (await stub.fetch(req)).json()。
这个决策应在配置阶段就定下,因为它决定了你的compatibility_date取值与代码写法。
九、常用命令:从本地开发到线上管理
开发
npx wrangler dev # Local dev npx wrangler dev --remote # Test against production DOswrangler dev在本地(Miniflare)运行 Worker 与 DO;加--remote则直接联通云端真实 DO,用于验证线上绑定与迁移后的行为。
部署
npx wrangler deploy # Deploy + auto-apply migrations npx wrangler deploy --dry-run # Validate migrations without deploying npx wrangler deploy --env production--dry-run是迁移安全的核心防线:它只做校验(tag 唯一/顺序、类名有效性等)而不真正上线,是第五节「不支持回滚」的补偿手段。--env production对应第六节的环境隔离部署。
管理
npx wrangler durable-objects list # List namespaces npx wrangler durable-objects info <namespace> <id> # Inspect specific DO npx wrangler durable-objects delete <namespace> <id> # Delete DO (destroys data)list:列出当前账户/环境下的 DO 命名空间。info <namespace> <id>:查看指定 DO 实例的元数据与状态。delete <namespace> <id>:删除指定实例——该操作销毁数据,与deleted_classes迁移同样不可逆,务必确认 ID 后再执行。
从 SKILL.md 可知,执行任何wrangler deploy类命令前应先npx wrangler whoami确认已认证;在沙箱环境中若部署网络调用被阻断,需要以sandbox_permissions=require_escalated重跑。
十、配置之外的实战要点:让配置真正落地
配置正确只是第一步,结合同目录文档可将配置价值最大化:
- 构造函数每次唤醒都会执行(冷启动或被 Hibernation 唤醒均如此),因此不要在构造函数里做重初始化,采用懒加载模式。这是 gotchas.md 反复强调的性能关键点。
- Hibernation 会清空内存态:所有关键数据必须写入
ctx.storage(SQLite/同步 KV/异步 KV)或使用ws.serializeAttachment()持久化连接级元数据,不能依赖类字段。 - 定时任务用
setAlarm()而非setTimeout:后者随实例驱逐而丢失,前者持久化存储、可跨驱逐触发,且失败会自动重试(但非 exactly-once,需幂等处理)。 - 单 DO 只有一个 Alarm:需要多个定时事件时,采用「事件队列 + 单一 Alarm」模式——存入带
runAt的事件,Alarm 触发时扫描到期事件并重排最近的下一个触发时间,详见 patterns.md。 - 单 DO 吞吐约 1K req/s:超过则用
newUniqueId()或哈希把负载分片到多个 DO(如按hash(userId) % 100分 100 片),这是 patterns.md 给出的 Sharding 方案。 - 竞态防护:DO 虽单线程,但
await是让步点,异步操作期间可能插入其他请求;关键区段使用ctx.blockConcurrencyWhile(),简单计数优先用 SQL 原子语句(INSERT ... ON CONFLICT DO UPDATE ... RETURNING)代替「读-改-写」。 - 高频低延迟存储用 SQLite SQL 与同步 KV:从 DO Storage 文档 的 API 划分看,SQLite 后端同时提供 SQL、同步 KV(
ctx.storage.kv)与异步 KV(ctx.storage)三种接口;同步接口免去await,适合热路径。
十一、快速上手:一份可直接落地的完整配置示例
把本文内容串起来,一个带 SQLite DO、环境隔离、CPU 限额的完整wrangler.jsonc如下:
{ "name": "my-worker", "main": "src/index.ts", "compatibility_date": "2025-01-01", "durable_objects": { "bindings": [ { "name": "COUNTER", "class_name": "Counter" } ] }, "migrations": [ { "tag": "v1", "new_sqlite_classes": ["Counter"] } ], "limits": { "cpu_ms": 300000 }, "env": { "production": { "durable_objects": { "bindings": [ { "name": "COUNTER", "class_name": "Counter", "environment": "production" } ] } } } }// src/index.ts import { DurableObject } from "cloudflare:workers"; interface Env { COUNTER: DurableObjectNamespace<Counter>; } export class Counter extends DurableObject<Env> { async increment(): Promise<number> { const result = this.ctx.storage.sql.exec( `INSERT INTO counters (id, value) VALUES (1, 1) ON CONFLICT(id) DO UPDATE SET value = value + 1 RETURNING value` ).one(); return result.value; } } export default { async fetch(request: Request, env: Env): Promise<Response> { const id = env.COUNTER.idFromName("global"); const stub = env.COUNTER.get(id); return new Response(`Count: ${await stub.increment()}`); } };本地npx wrangler dev验证,通过后npx wrangler deploy --dry-run预检迁移,再npx wrangler deploy上线,生产环境使用npx wrangler deploy --env production。
延伸阅读
- Durable Objects 概览与决策树
- Durable Objects API:ctx 方法、Alarm、WebSocket Hibernation
- Durable Objects 实战模式:分片、限流、分布式锁、会话、多事件队列
- Durable Objects 常见坑与完整限额表
- DO Storage 深度指南:SQLite / KV / PITR / 事务
- cloudflare-deploy skill 总览与部署前置要求
【免费下载链接】skillsSkills Catalog for Codex项目地址: https://gitcode.com/GitHub_Trending/skills4/skills
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考