当你的客户想运行自己的工作流,你该怎么办
一个平台开发者绕不开的困境假设你在构建一个 SaaS 平台你的客户可以在上面写自己的业务逻辑——也许是一个低代码工具也许是一个 AI 驱动的自动化平台也许是一个让每个团队定义自己 CI 流水线的开发工具。客户的逻辑各不相同甚至在你部署代码的那一刻你根本不知道他们会写什么。但有一件事是共同的这些逻辑往往不是简单地执行一下就结束的。它们需要等待外部事件需要在某个步骤失败时自动重试需要在等待人工审批时暂停需要在服务器重启后从断点继续执行。这就是持久执行问题。在 Cloudflare 的解法体系里负责处理持久执行的产品叫 Workflows。但 Workflows 有一个内置假设工作流的代码必须在部署时就确定好。你在配置文件里声明一个绑定指向一个固定的类一旦部署就定死了。这在你自己写所有代码的时候完全没问题。一旦你想让客户带来他们自己的工作流这个假设就彻底失效了。2026 年 5 月Cloudflare 正式发布了Dynamic Workflows专门解决这个问题。先理解持久执行在解决什么在深入 Dynamic Workflows 之前有必要先说清楚持久执行Durable Execution的价值是什么。传统的 HTTP 请求处理模型是无状态的收到请求处理返回结果完毕。如果处理过程中服务崩溃了请求就丢了需要客户端重试。这对大多数 API 调用来说够用但对于需要运行几分钟、几小时甚至几天的流程来说这个模型根本无法胜任。Cloudflare Workflows 的核心能力是把一个包含多个步骤的函数变成一个可以跨越故障、睡眠和重启继续执行的程序。每个step.do()的结果会被持久化即使运行环境被销毁下次唤醒时也会从上次完成的地方继续而不是从头开始。等待外部事件可以用step.waitForEvent()暂停 24 小时可以用step.sleep(24 hours)整个过程不需要占用任何计算资源。这是为需要一直跑下去的场景设计的用户注册流程、视频转码管道、多阶段账单处理、长时间运行的 AI Agent 任务循环。问题在于这套机制一直有一个前提工作流的代码是你自己写的并且在部署时就绑定好了。在多租户场景里客户的代码是运行时才出现的部署时根本不存在。三块拼图现在凑齐了过去一段时间Cloudflare 在动态部署方向一直在推进但覆盖的是不同的层次Dynamic Workers已开放测试解决的是计算层的问题在运行时把一段代码交给 Workers 运行时立刻得到一个隔离沙箱单位毫秒级启动不需要预先部署。Durable Object Facets把同样的思路延伸到了存储层每个动态加载的应用可以拥有自己的 SQLite 数据库按需创建平台作为上层协调者管理访问。Artifacts把这套模式带到了源码管理层一个 Git 原生的版本化文件系统可以按每个 Agent、每个会话、每个租户创建数量不设上限。计算动态了存储动态了持久执行这一层一直还是静态的——必须预先部署必须绑定到固定的类。Dynamic Workflows 填补了这个空缺。现在这三块拼图凑齐了。Dynamic Workflows 是什么从外部看cloudflare/dynamic-workflows是一个大约 300 行 TypeScript 代码的小型库。它解决的核心问题可以用一句话概括让一个 Worker称为 Worker Loader能够把每个create()调用路由到不同租户的代码并且在工作流引擎后续唤醒执行时依然能找回同一份租户代码。后续唤醒是这里的关键词。工作流引擎可能在第一步执行完之后间隔几秒、几小时、甚至几天才来执行第二步。在这段时间里当时加载的代码早已不在内存里了。Dynamic Workflows 要解决的正是当引擎再次唤醒时如何准确地把执行权交还给同一个租户的代码而不是找错地方。三层架构整个执行流程涉及三层角色最上层Workflows 引擎Cloudflare 平台负责持久化状态、调度执行、管理重试和休眠。中间层Worker Loader你平台开发者编写的调度层负责根据租户标识加载对应代码充当引擎和租户代码之间的路由器。最下层租户代码通过 Dynamic Workers 在运行时动态加载的沙箱化 Worker包含租户自己写的工作流逻辑。租户视角对于租户来说他们写的代码和普通的 Cloudflare Workflows 代码完全一样import{WorkflowEntrypoint}fromcloudflare:workers;exportclassTenantWorkflowextendsWorkflowEntrypoint{asyncrun(event,step){returnstep.do(greet,async()Hello,${event.payload.name}!);}}exportdefault{asyncfetch(request,env){constinstanceawaitenv.WORKFLOWS.create({params:awaitrequest.json()});returnResponse.json({id:awaitinstance.id});},};租户不需要知道自己的代码是被动态加载的不需要知道存在一个 Worker Loader 在中间路由不需要了解任何平台细节。env.WORKFLOWS在他们看来就是一个普通的 Workflows 绑定.create()、.status()、.pause()、重试、休眠、等待外部事件全部照常工作。一次请求的完整生命周期理解 Dynamic Workflows 的工作机制最直观的方式是跟着一次请求走一遍完整流程。进入阶段HTTP 请求到达 Worker LoaderLoader 识别出这是哪个租户的请求通过 Dynamic Workers 加载该租户的代码把请求转发给租户的default.fetch。注入给租户的env.WORKFLOWS实际上是一个经过包装的绑定外表和真实 Workflows 绑定一模一样。上报阶段当租户调用env.WORKFLOWS.create({ params })时这个调用实际上触发了一次 RPC把请求连同租户标识一起发送回 Worker Loader。Loader 把租户标识嵌入到参数信封中然后用真实的 Workflows 绑定把这个信封提交给引擎租户调用create({ params: { name: Alice } }) ↓ 引擎收到create({ params: { __workerLoaderMetadata: { tenantId: t-42 }, params: { name: Alice } }})持久化与调度Workflows 引擎接管持久化整个 payload包含租户标识信封安排执行。唤醒阶段当引擎准备好执行某个步骤时它调用 Worker Loader 中预先注册的入口类。该类从信封里解包租户标识调用你编写的回调函数加载对应租户的代码把执行权转交过去。租户的run(event, step)收到的是已经解包的干净 payload完全感知不到中间发生的路由过程。缓存优化Worker Loader 对租户代码按 ID 缓存。同一个工作流执行多个步骤期间如果隔离实例还在会直接复用不需要重复加载。如果实例被回收下一个步骤触发时重新加载对工作流本身完全透明。一个 Dynamic Worker 启动只需要个位数毫秒内存占用极小这部分开销基本可以忽略不计。三个最值得关注的使用场景AI Agent 平台当前最先进的编程 AgentClaude Code、Codex、OpenCode 等有一个被反复验证的结论让 LLM 写代码远比让它进行一系列工具调用更可靠。Dynamic Workflows 让这个洞察延伸到了持久执行的维度Agent 写出的工作流可以直接作为 Cloudflare Workflows 运行带着完整的耐久性机制。Agent 写出一个run(event, step)函数每个step.do()独立可重试每个step.sleep(24 hours)免费休眠每个step.waitForEvent()等待人工审批时不占用任何资源。Agent 不需要知道平台细节平台也不需要提前知道 Agent 会写什么计划。SDK 与低代码框架如果你在构建一个工作流可视化工具、一个允许非开发者定义自动化流程的平台、或者一个让用户自定义业务逻辑扩展点的 SDKDynamic Workflows 是让这一切真正落地的底层原语。你负责 Worker Loader 这一层用户负责工作流逻辑这一层两者之间有清晰的边界。用户写的每个工作流实例自动带上标识、路由、沙箱隔离平台不需要知道也不需要关心用户逻辑的具体内容。CI/CD这是 Cloudflare 在博客里描述为最让人兴奋的场景也是最能展示这套原语组合威力的地方。重新构想 CI/CD 的底层所有 CI/CD 平台的本质都是同一件事读取一个描述运行这些步骤的配置文件然后执行它。每个仓库有自己的流水线每个分支可能有自己的变体每个 PR 都会产生一个独立的运行实例这个实例需要跑到完成、在中途崩溃时恢复、在等待人工审批时暂停。这是一个持久执行问题的标准模型。但直到现在没有人能这样构建 CI因为缺少一个关键原语工作流本身对每个仓库都不同需要在运行时加载且不需要提前预置任何资源。Dynamic Workflows 就是这个原语。下面是一个完整的 CI Pipeline 示例这是仓库里的.cloudflare/ci.ts文件由 Cloudflare 平台在收到 webhook 时动态加载和执行import{WorkflowEntrypoint}fromcloudflare:workers;exportclassCIPipelineextendsWorkflowEntrypoint{asyncrun(event,step){const{repo,sha,branch,pr}event.payload;// 秒级 fork不是 git cloneconstworkspaceawaitstep.do(checkout,()this.env.ARTIFACTS.fork(repo,{sha}));awaitstep.do(install,()runInSandbox(workspace,[pnpm,install]));// 三步并行每步独立可重试const[lint,test,build]awaitPromise.all([step.do(lint,()runInSandbox(workspace,[pnpm,lint])),step.do(test,()runInSandbox(workspace,[pnpm,test])),step.do(build,()runInSandbox(workspace,[pnpm,build])),]);if(pr){awaitstep.do(comment,()this.env.GITHUB.commentOnPR(repo,pr,summarise({lint,test,build})));}// 等待审批时完全不占用资源免费休眠最多 24 小时if(branchmain){awaitstep.waitForEvent(approval,{type:deploy-approval,timeout:24 hours});awaitstep.do(deploy,()runInSandbox(workspace,[pnpm,deploy]));}}}这段代码里每个参与的基础能力都有明确分工Artifacts提供 Git 原生的版本化文件系统fork()在秒级内给每次 CI 运行提供一份隔离副本没有git clone的网络开销。Dynamic Workers在同一台机器上用隔离的沙箱运行每个轻量步骤lint、类型检查、打包等毫秒级启动不需要分配 VM不需要拉镜像。Dynamic Workflows把整个流程串联成持久执行步骤独立可重试等待审批时完全休眠状态在崩溃和重启后自动恢复。Sandboxes处理那些真正需要完整操作系统环境的步骤比如docker build、需要 PostgreSQL 的集成测试快照存储在 R2 上冷启动也只需要几秒。对比一下传统 CI 的时间构成分配 VM 需要 15-30 秒拉取基础镜像需要 10 秒git clone需要 10 秒npm ci需要 30-60 秒然后才开始跑真正的测试。用户在等待几分钟的准备工作之后才能看到第一个测试结果。而且整个 VM 在全程都需要保持活跃包括等待人工审批的那段时间。新的方案仓库文件系统秒级就绪每个步骤用一个新的沙箱实例执行毫秒级启动执行完即释放等待审批时没有任何计算资源在运行。没有预热没有预置什么都不需要提前准备好。更大的图景一切绑定都将迎来动态版本Dynamic Workflows 的底层是 Dynamic Workers。实际上这篇博客里大部分有趣的代码都只是在做两件事在出站方向包装.create()调用在入站方向包装WorkflowEntrypoint。真正的重活——代码加载、沙箱隔离、RPC 跨边界路由、隔离实例缓存、步骤间休眠——全都由 Dynamic Workers 完成。这揭示了一个更大的方向。Cloudflare 明确表示Workers 今天支持的所有绑定类型都将陆续获得动态版本——每个生产者可以带来自己处理逻辑的消息队列、按租户动态绑定的缓存和数据库、AI 绑定、MCP Server都会支持按租户、按 Agent、按请求动态分派闲置时零成本。这对多租户平台的经济模型来说意味着什么过去构建一个给多个客户使用的 SaaS 平台意味着给每个客户分配独立的容器、独立的数据库、独立的存储、独立的调度器再用服务网格和编排工具把它们粘合起来。稍有规模的平台就需要管理数以千计的客户资源成本随客户数量线性增长。在 Dynamic Workers 和建立在其上的这套原语里空闲租户的成本约等于零活跃租户通过隔离级别的多租户共享同一套硬件。平台的客户规模上限从数千变成了数千万而成本结构的地板降低了好几个数量级。写在最后Dynamic Workflows 目前以 MIT 协议开源已发布到 npmnpminstallcloudflare/dynamic-workflows它运行在 Dynamic Workers 之上后者目前在 Workers 付费计划中开放公测。GitHub 仓库里包含一个可以直接运行的示例——一个浏览器内的交互式沙盒你可以在里面写一个TenantWorkflow类点击 Run实时看到每个步骤的执行日志和完成状态。如果你在构建多租户平台、AI 应用框架、工作流工具或 CI/CD 产品Dynamic Workflows 解决的正是那个最麻烦的问题客户的逻辑是运行时才知道的但持久执行又必须在部署时绑定好。这个矛盾现在有了一个干净的答案。原文来源Cloudflare Blog《Introducing Dynamic Workflows: durable execution that follows the tenant》2026 年 5 月 1 日。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2601658.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!