Cloudflare Workflows 和 Queues 怎么选?
用 Queues 拼一个状态机是可行的:每一步发一条消息,消息体里带「当前状态」。但重试、超时、等待,还有「这个订单卡在哪一步」的排查,都要你自己实现,状态散落在消息和数据库里。
判断标准只有一条:只要出现「第二步依赖第一步的结果」或「要等一段时间、一个外部信号」,就用 Workflows;只做单步异步、批量扇出,就用 Queues。
两者的核心差别是谁持有流程状态。下面先把这个差别讲清楚,再讲它们怎么首尾相接,以及这种组合白送的一个去重能力。
两者到底差在哪?
- Queues:消息是独立的,没有「流程」概念;顺序只是 best effort;平台只负责投递与重试。适合独立、无依赖的小任务,以及削峰。
- Workflows:实例是一个有状态的流程,步骤顺序、已完成步骤的结果、等待的事件都由平台持久化。适合多步骤、有依赖、要等待、要补偿的业务。
Queues 的投递语义、重试与死信,见 Queues。Workflows 自身怎么持久化步骤,见 Workflows 怎么让长流程不从头再来。
能不能把两者组合起来?
可以,而且很常见:Queues 负责接入与削峰,每条消息创建一个 Workflow 实例。官方文档明确支持在 queue 处理器里调用 create 触发 Workflow。
const instance = await env.ORDER_FLOW.create({ id: `order-${orderId}`, params: { orderId, email } });这样 Queues 吸收流量尖峰,Workflows 负责每一单的流程状态,各管各的。
消息重复投递会创建两个流程吗?
不会,前提是你用确定的实例 ID。ID 在保留期内不能复用,create 遇到重复 ID 会抛错,本地我看到的错误是 instance.already_exists。所以重复投递的消息会因为 ID 已存在而被拒绝,这是一种免费的幂等去重。
关键是用业务上稳定且唯一的 ID,比如 order-<orderId>,让「同一订单只会有一个流程」成为由构造保证的不变量,而不是靠代码里的判断。若一个业务对象需要多次流程,ID 里加上流程类型或序号。
要一次创建很多实例怎么办?
用 createBatch。官方文档说,重复 ID 不会抛错,而是列入 errors。
我在本地跑了对象形式 createBatch({ instances }):它返回 { created, errors },同一批里的重复 ID 与已存在的 ID 都会出现在 errors 里,并带错误码。
对象形式需要较新的 Wrangler,官方文档标注 4.148.0 及以上;旧的数组形式已被标为 deprecated。
那 Durable Objects 呢?
它解决的是另一个问题。需要对同一个 key 做串行协调或实时连接,用 Durable Objects;需要一条可靠走完的长流程,用 Workflows。
create遇到重复 ID 抛instance.already_exists,以及对象形式createBatch返回{ created, errors }、重复与已存在 ID 都进errors,是我在本地 wrangler dev 上跑过的。在queue处理器里触发 Workflow、Wrangler 4.148.0 版本要求、旧数组形式 deprecated,只是官方文档的说法,我没有验证。版本与行为会变化,以官方文档为准。官方参考:Workers API。