凌晨对账任务跑了两遍,问题比不跑更棘手

凌晨两点,财务同事发来消息:同一笔对账结果出现了两条记录,金额一致、时间相近,像是任务被完整跑了两遍。奇怪的是,系统没有报错,任务状态也显示成功。这类问题比任务不执行更难排查,因为“跑成功”掩盖了“跑重复”的事实,日志里往往只留下两份看起来都正常的执行记录。处理定时任务重复执行,不能一上来就改代码,而应按调度层、执行层、业务层的顺序逐层核对,先找到重复的来源,再决定在哪一层收口。

先看调度层:同一任务是否被多处触发

第一步要确认任务到底被触发了多少次、由谁触发。常见情况有三种:集群中多个节点都拿到了同一把调度锁,各自启动了一次;新旧两套调度系统并行运行,同一份配置被两边同时加载;人工在管理后台点了一次“立即执行”,而定时触发恰好也到点。核对方法是拉出任务触发记录,按任务标识和时间窗口统计触发次数,再对照各节点的调度日志,看是否存在同一时刻多条触发来源。如果触发次数本身就大于一,问题在调度层,先解决锁与配置归属,不要急着往下查。

再查执行层:重试与补跑是否叠加

如果触发只有一次,执行却出现了多份结果,就要看执行层的重试机制。任务执行超时后自动重试,是常见设计,但如果超时判断偏短、任务实际仍在运行,重试就会与上一次执行并行;失败补偿任务如果配置了全量重跑,也可能把已经成功的部分再跑一遍;再加上人工手动补跑,三种来源叠加,就会出现重复。核对时重点看每次执行的开始时间、结束时间与重试标记,确认是否存在时间区间重叠的执行实例。重叠即意味着并发,并发就意味着重复风险。

最后看业务层:幂等设计是否真正生效

调度和执行都正常,仍然出现重复数据,说明业务层缺少有效的幂等控制。常见做法是给每笔业务加唯一幂等键,写入前去重表查询,或用状态机限制同一单据只能从待处理流转到已处理一次。核对时要验证三点:幂等键是否覆盖了业务主键与任务批次的组合;去重表是否在事务内写入,避免并发穿透;状态流转是否带条件更新,防止后写覆盖先写。很多重复问题不是没有幂等设计,而是幂等键选得太粗,同一批次内不同记录被当成同一条。

六项核对清单与灰度验证

实际排查可以按这份清单推进:一查触发记录次数与来源;二查集群锁是否只有单一持有者;三查是否存在新旧调度并行;四查重试与补跑的时间区间是否重叠;五查幂等键是否唯一且覆盖批次;六查状态更新是否带条件。修改后不要直接全量上线,先选一个非核心任务做灰度,观察一到两个调度周期,确认触发次数、执行实例数与业务落库数三者一致,再逐步放开。

日志留痕与告警的作用

重复执行往往在发生后几天才被发现,因此日志留痕比事后排查更重要。建议在触发、开始执行、执行结束、业务落库四个节点各留一条带任务标识与批次号的记录,并对同一任务短时间内的多次触发设置告警。it数运在软件维护流程中习惯把调度记录与业务落库记录分开留存,便于对照定位重复来源。把核对顺序固定下来,重复执行就不再是偶发的谜题,而是可以逐层收敛的常规问题。

© 版权声明
THE END
点赞7 分享