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。安全做法是保留旧流程版本,或者用显式版本分支。
小练习
- 在
charge-payment后崩溃,观察第二次 attempt 是否跳过扣款。 - 在
reserve-inventory后崩溃,比较 Journal 里已有几个 step。 - 修改步骤顺序后重放旧 invocation,观察错误并解释原因。