在任务调度系统中,任务的重试机制和队列管理是确保任务按时执行的关键部分。然而,当任务队列满时,任务的重试可能会出现计划永久偏移的现象。这种现象通常发生在任务被改期到一分钟后,但随后的所有执行时间都基于改期后的时间计算,而不是原先的节奏。这种情况在任务调度系统中可能会导致任务执行的不准确性和不可预测性,影响系统的稳定性和效率。

现象描述

当任务在触发瞬间若任务队列已满,会被改期到一分钟后。但此后的所有执行时间都基于改期后的时间计算,而不是原先的节奏,导致计划永久偏移。

原因分析

在任务调度系统中,有一个名为 Busy 的分支执行了 UPDATE schedules SET next_run_at = now + BUSY_RETRY_MS 的操作。这个操作将任务的下次执行时间设置为当前时间加上 BUSY_RETRY_MS 毫秒。下次 run 读取该值作为 due,following() 函数便从这个新起点继续推算。此外,request_key 中包含了 due 信息,用于重试的任务已经使用了另一个 key。

复现步骤

  1. 计划设置:首次任务计划在 10:00 执行,每 60 分钟执行一次。
  2. 队列满的情况:在 10:00 时,任务队列已满,任务被改期到 10:01 执行。
  3. 实际执行:任务实际在 10:01 执行。
  4. 后续执行:之后依次是 11:01、12:01,且每次队列满都会再叠加偏移。

这种现象表明,任务调度系统在处理队列满的情况时,存在一定的缺陷。任务的重试机制和队列管理需要进一步优化,以确保任务能够按照预期的时间表执行。此外,系统的设计应该能够避免因队列满而导致的任务计划永久偏移问题,从而提高系统的可靠性和稳定性。