跑上几小时的长任务最怕的不是模型答错,而是中途断掉之后一切归零。一次调用超时、一次工具服务抖动、一次进程重启,都可能让已经跑完的几十步白白重来。断点续跑要解决的核心问题只有一个:任务在任意时刻被打断,都能从离断点最近的一致状态继续,而不是从头开始。做到这一点,靠的不是把日志打得更全,而是把任务状态设计成可恢复的。

第一步是把任务拆成可重入的步骤。每个步骤应当有明确的输入、输出和完成标志,执行完一步就把结果写进持久化存储,再推进下一步。步骤本身要尽量满足幂等性:同一输入重复执行,产生同样的结果,不重复扣款、不重复发单、不重复写库。幂等键可以取任务编号加步骤序号,工具侧用它去重,恢复时先查幂等记录,再决定是跳过还是重放。没有幂等性保证的步骤,断点续跑就退化成碰运气。

第二步是检查点的粒度。检查点太稀,恢复时要重算很多;太密,写盘和序列化本身又成了负担。一个实用的做法是分层设点:关键里程碑处写完整快照,包括已完成步骤的结果、待办队列和外部资源句柄;普通步骤之间只写增量记录。恢复时先加载最近的快照,再按顺序重放增量记录,直到追上断点。快照要带版本号,结构一变就升版本,老快照用迁移函数转换,避免新代码读不懂旧状态。

第三步是区分可恢复与不可恢复的失败。工具返回超时、限流、临时不可用,属于可恢复,退避重试几次仍失败再挂起任务等待人工或定时唤醒;参数错误、权限被拒、目标资源已删除,属于不可恢复,应当立刻停下并把现场封存,而不是无限重试。恢复策略本身也要有上限:同一任务在短时间内反复失败,就应当降级为人工介入,防止重试风暴把下游服务拖垮。

最后是恢复后的校验。续跑不是简单地接着跑,还要先确认世界没有变:依赖的外部数据是否过期、之前写入的结果是否还有效、后续步骤的前提条件是否仍然成立。校验不过的步骤应当标记为待复核,宁可停下来问人,也不要在过期状态上继续推进。断点续跑的工程目标从来不是永不中断,而是中断之后损失可控、恢复过程可预期。