
今天在生产环境出现问题了,之前我开发了一个月底批量生成订单的定时任务,用的是若依定时任务的模块,我当时配置的是每个月25号的凌晨来执行这个任务,但是今天却发现9月份生成的订单重复了两次造成了大量的脏数据内容。
当时的配置如下

查看日志发现有两个连续的执行任务记录:
执行状态 执行时间
成功 2025-09-25 00:00:41
成功 2025-09-25 00:00:00 这个任务在同一分钟内被连续触发了两次,由于本身订单的生成逻辑就不是幂等的,所以导致系统最终生成了重复的数据
后面排查后我发现,问题主要是出来底层定时任务Quartz的Misfire执行策略配置上面,之前对这个东西的了解并不是很深。
三种执行策略:
策略类型 | 行为描述 |
|---|---|
立即执行 | 所有错过的任务(misfire)会立即执行 |
执行一次 | 只执行一次 misfire 任务,合并部分错过的执行 |
放弃执行 | 所有 misfire 任务都跳过,等待下一个周期 |
在我这个定时任务的配置中,我当时执行策略配置的是立即执行。
然后系统在 0 点的时候需要执行的各种任务非常多,资源调度会瞬间变得紧张起来,调度器可能会出现短暂“卡顿”或者“类似重启”的情况。
Quartz 检测发现到这种异常后,根据这个策略规则就会马上把认为漏掉的任务再执行一遍,结果就造成了重复。
我确定问题之后,主要从三个方面做了优化。
这样就算定时任务因为系统负载过高或者调度延迟时,也不会补这个任务再次跑一次。
0点是系统的高峰期,加上我们本身这个月底自动的任务量也比较大,执行的操作以及调度功能都比较多,因此将时间错开留出一个单独的时间来专门处理这个定时任务,可以较大效率的降低风险。
因为我这个业务还需要保留手动补全的功能,不能直接判断是否已经存在当月数据就跳过不执行的方式来避免这个问题,因此我选择使用5分钟内重复触发的校验:
// 伪代码示例
if (最近5分钟内该任务已执行过) {
throw new RuntimeException("重复触发任务,终止执行");
}实现思路: 可以用Redis记录执行过的时间戳,下一次处罚的时候来进行校验判比; 如果本次触发的当前时间 - 上次执行时间 < 5 分钟,则判定为重复则抛出异常。
不同的策略适合不同场景,根据所需的业务要求来搭配相适应的策略。
这样可以避免在 0 点整 的时间去安排多个重要任务。
同一时间段、同一批次的数据只允许被生成一次。
OKk,梳理完毕,这次生产问题造成的脏数据可以指定批量删除掉恢复正常,但是也暴露了我对执行策略理解的层次不够的问题。加以重视,以后情况可以避免更严重的后果。
希望这篇文章也能够开发者提前规避潜在风险。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。