任务跑到一半断电,重启后该从哪里继续?
最危险的不是没执行,而是不知道执行了没有
订单助手准备创建补货单。它先生成请求,服务端已经创建订单并返回编号,但本地还没来得及保存结果就断电。重启后日志只看到“准备创建”,如果简单重放最后一个动作,会再建一张相同订单。反过来,如果一律认为动作已经完成,也可能把真正未执行的请求漏掉。
这叫不确定执行窗口:外部副作用和本地记录不在同一个事务里。保存对话文本有帮助,却不能自动把两边状态绑定成一次原子操作。恢复策略必须区分动作尚未发出、已发出但结果未知、已确认并持久化三个状态。
先认识两个不同的“保存”
会话持久化保存任务、事件、待执行动作与恢复位置;工作空间持久化保存实际文件或执行环境。会话还在但工作目录丢了,模型可能引用不存在的产物;文件还在但日志丢了,模型可能不知道文件由谁生成、是否核验。远程订单服务又有第三套状态,不能只恢复本地目录就宣称全部恢复。
三个断点,一张明确的恢复表
断点A在发送创建请求之前。日志保存了意图但确认尚未发送,可以用同一稳定请求标识发送。断点B在服务已创建之后、结果入库之前。本地不知道是否成功,应先向服务查询请求标识,或用服务支持的幂等键重试。断点C在订单编号与成功结果已经可靠保存之后。应直接使用该结果继续通知或汇总,不再创建。
幂等键的意思是同一业务意图使用同一个键,多次提交返回同一个已创建结果,而不是每次新建。例如任务T8的补货单创建使用键 T8:create-replenishment:v1。重试时随机生成新键会失去去重作用;把不同补货单误用同一键,则可能错误复用旧结果。键应绑定明确业务意图与参数,服务还需定义冲突和有效期。
在三个断点中恢复同一个意图
先预测结果,再逐步查看;切换条件时留意是哪一个中间量改变。案例是教学构造的规则回放,不是模型训练实测。
教学构造场景 · 按下方规则逐步回放;不调用真实模型,不代表实际成功率。
意图已保存,服务尚未收到创建请求
- 1. 读检查点
确认状态为未发送。
- 2. 恢复身份
核对任务仍有效,复用稳定幂等键。
- 3. 执行并保存
发送创建请求,持久化订单编号与完成状态。
确认状态为未发送。
先预测,再核对结果与原因
创建一次后继续后续工作。恢复依据执行状态,不只依据最后一句对话。
读操作也值得做检查点,但理由不同
搜索供应商资料成功后,可以先把搜索结果持久化,再让模型生成建议。若生成阶段崩溃,恢复时复用已经保存的搜索结果,避免再花费用和因网页变化获得不同证据。这里主要解决重复计算与可追溯性,和创建订单避免重复副作用相关,却不是同一个保证。
两个条件变化会让恢复策略失效
第一,外部服务不支持幂等键,也无法按业务标识查询。此时对不可逆创建动作不能保证安全自动重试;应把状态标为待核对,交由有权限的人或补偿流程处理,而不是猜测。只读查询通常可重试,但也应考虑费用、速率限制和数据时间变化。
第二,任务在等待期间被用户取消。恢复器不能只看旧日志里有待执行动作就继续创建;需要检查当前任务状态与授权。恢复是继续一个仍有效的任务,不是无条件重播历史脚本。目标参数若已经改变,应产生新的业务意图,不能悄悄复用旧键。
用故障注入验证,而不是只测正常通路
对教学系统,在三个断点主动模拟停止,再恢复,检查服务最终只存在一张订单、本地保存同一编号、后续步骤只处理一次。另测“服务成功但响应丢失”“日志写入失败”“取消后恢复”。只运行一次正常流程不会暴露这些窗口。
日志要保存稳定动作ID、幂等键、请求摘要、状态转移、外部结果编号与时间,不要存不必要的秘密。恢复后还应核对输入版本与环境,避免代码或工具语义变化使旧动作产生不同效果。所谓恰好一次通常需要外部系统配合,不能由一个客户端重试循环单方面承诺。
下一课把这些状态与事件接到自动交付:收到issue、开始修改、测试、产物审查,每一步都有不同完成条件。能恢复只是保证流程能继续;是否应该进入下一关,还需要证据。
用自己的话核对一次
重试时换一个随机幂等键更安全吗?
展开解释
不是。同一业务意图需复用稳定键,换键会被服务视为新请求;不同意图则不能误用同一键。
恢复会话就恢复了工作目录和订单服务吗?
展开解释
不一定。它们有不同存储与生命周期,需分别核对持久化范围与真实状态。
外部不支持去重也不能查询,未知创建可自动重试吗?
展开解释
不能保证不重复。应保留未知状态并核对,尤其不可逆副作用;客户端重试本身无法实现跨系统恰好一次。