当你的客户想运行自己的工作流,你该怎么办

news2026/5/10 21:12:14
一个平台开发者绕不开的困境假设你在构建一个 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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…