news 2026/9/12 11:06:34

Cloudflare Durable Objects 配置实战指南:wrangler.jsonc 绑定、数据本地化与迁移机制全解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Cloudflare Durable Objects 配置实战指南:wrangler.jsonc 绑定、数据本地化与迁移机制全解

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_objectsmigrations两个块,完整示例如下:

{ "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_classesnew_classes分别对应两种 DO 存储后端,差异见 DO Storage 概览:

后端创建方式可用 API30 天时间点恢复(PITR)
SQLite(推荐)new_sqlite_classesSQL + 同步 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 MBSQLite/异步 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 语义/代理/遗留兼容)以及生命周期处理器(alarmwebSocketMessagewebSocketClosewebSocketError)。

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 DOs

wrangler 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重跑。

十、配置之外的实战要点:让配置真正落地

配置正确只是第一步,结合同目录文档可将配置价值最大化:

  1. 构造函数每次唤醒都会执行(冷启动或被 Hibernation 唤醒均如此),因此不要在构造函数里做重初始化,采用懒加载模式。这是 gotchas.md 反复强调的性能关键点。
  2. Hibernation 会清空内存态:所有关键数据必须写入ctx.storage(SQLite/同步 KV/异步 KV)或使用ws.serializeAttachment()持久化连接级元数据,不能依赖类字段。
  3. 定时任务用setAlarm()而非setTimeout:后者随实例驱逐而丢失,前者持久化存储、可跨驱逐触发,且失败会自动重试(但非 exactly-once,需幂等处理)。
  4. 单 DO 只有一个 Alarm:需要多个定时事件时,采用「事件队列 + 单一 Alarm」模式——存入带runAt的事件,Alarm 触发时扫描到期事件并重排最近的下一个触发时间,详见 patterns.md。
  5. 单 DO 吞吐约 1K req/s:超过则用newUniqueId()或哈希把负载分片到多个 DO(如按hash(userId) % 100分 100 片),这是 patterns.md 给出的 Sharding 方案。
  6. 竞态防护:DO 虽单线程,但await是让步点,异步操作期间可能插入其他请求;关键区段使用ctx.blockConcurrencyWhile(),简单计数优先用 SQL 原子语句(INSERT ... ON CONFLICT DO UPDATE ... RETURNING)代替「读-改-写」。
  7. 高频低延迟存储用 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),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/12 11:04:15

燃料电池Simulink建模与仿真技术解析

1. 燃料电池Simulink建模的价值与挑战 燃料电池作为清洁能源技术的代表&#xff0c;其建模与仿真一直是工程研发的关键环节。我在新能源汽车行业工作十年间&#xff0c;亲眼见证了Simulink如何从辅助工具成长为燃料电池系统开发的核心平台。不同于传统的黑箱测试&#xff0c;基…

作者头像 李华
网站建设 2026/9/12 11:02:13

音频转MIDI技术突破:Prism插件实战解析

1. 音频转MIDI革命&#xff1a;Aurally Sound Prism插件深度解析 作为音乐制作领域的老兵&#xff0c;我见证过无数次"音频转MIDI"技术迭代的失望时刻——直到遇见Prism这款真正能用的解决方案。这款由Aurally Sound推出的跨平台插件&#xff0c;首次实现了复杂乐器音…

作者头像 李华
网站建设 2026/9/12 11:00:58

MQTT发布订阅、QoS与遗嘱消息实战解析

1. 这不是教科书里的协议图&#xff0c;而是一套真实设备间“说人话”的通信系统你手头正调试一块EC20 4G模块&#xff0c;想把它连上阿里云IoT平台&#xff1b;或者你在Vue3项目里写MQTT连接逻辑&#xff0c;connect之后死活收不到topic消息&#xff1b;又或者你在RuoYi框架里…

作者头像 李华
网站建设 2026/9/12 11:00:40

AI Agent实时对话意图识别技术解析与实践

1. 项目概述&#xff1a;AI Agent实时对话意图识别的核心价值在智能交互领域&#xff0c;实时对话意图识别系统如同给机器装上了"读心术"。这个我在多个工业级项目中反复验证过的技术&#xff0c;能够将用户零散的语音或文字输入&#xff0c;在300毫秒内转化为结构化…

作者头像 李华
网站建设 2026/9/12 10:58:48

ZLUDA完整教程:在AMD显卡上运行未修改的CUDA程序

ZLUDA完整教程&#xff1a;在AMD显卡上运行未修改的CUDA程序 【免费下载链接】ZLUDA CUDA on non-NVIDIA GPUs 项目地址: https://gitcode.com/GitHub_Trending/zl/ZLUDA 假设你的机器装着一张AMD显卡&#xff0c;而你想跑的软件是用NVIDIA的CUDA工具链编译的——比如CU…

作者头像 李华