Skip to content

Demo 03:崩溃恢复与重放

有了 Journal,下一步是让 worker 在失败后重新调度 invocation,并在重放时跳过已完成步骤。

状态机

教学版 invocation 状态如下:

故障注入

最终项目支持一个教学参数:

json
{
  "sku": "book",
  "quantity": 1,
  "amount": 99,
  "crash_after": "charge-payment"
}

第一次 attempt 在 charge-payment 后故意抛错。worker 将 invocation 标为 RETRYABLE,下一轮重新执行 handler:

重放要求业务代码“结构稳定”

如果你在两个版本之间改变 step 顺序,会发生什么?

旧版本:

python
ctx.run("charge-payment", charge)
ctx.run("reserve-inventory", reserve)

新版本:

python
ctx.run("reserve-inventory", reserve)
ctx.run("charge-payment", charge)

对已经运行中的 invocation 来说,step 0 的含义变了。重放可能把“扣款结果”当成“库存结果”。生产系统需要更强的 entry 类型校验、版本化和部署排空策略。

演进规则

对已有未完成 workflow,不能随意重排、删除、插入 durable steps。安全做法是保留旧流程版本,或者用显式版本分支。

小练习

  1. charge-payment 后崩溃,观察第二次 attempt 是否跳过扣款。
  2. reserve-inventory 后崩溃,比较 Journal 里已有几个 step。
  3. 修改步骤顺序后重放旧 invocation,观察错误并解释原因。

Teaching project inspired by Restate's public architecture and documentation.