如果不保留上次完成的日期,Laravels 任务计划如何工作?



Laravel通过AppConsoleKernel@schedule方法(正确)运行计划任务。它不需要持久性层即可做到这一点。以前运行的计划任务不会保存到数据库中,也不会存储在其中。

这种"魔力"是如何实现的?我想有更深入的理解。

我已经查看了源代码,我可以看到它在某种程度上是通过四舍五入当前日期并将其与计划频率进行比较来实现的,再加上它需要每分钟运行一次的事实,它可以以一定程度的信心说它应该运行一个任务。这是我的解释,但我仍然无法完全理解它如何保证按计划运行,以及它如何处理故障或事情偏离几秒钟。

编辑由于评论中指出的清晰度问题而编辑

我所说的"几秒钟"是指"向下舍入"方法如何工作,即使它每分钟运行一次,但不是在同一秒运行 - 示例:第一次运行 00:01.00、00:01:02、00:02:04

也许为了进一步澄清,并有助于理解它是如何工作的,是否有任何关于它如何运作的边界保证?如果每分钟运行多次,它会在一分钟内多次执行每分钟任务吗?

Cronjob不能保证精确秒数。这就是为什么通常没有 cronjob 间隔小于一分钟的原因。因此,实际上,它不会处理"事情偏离几秒钟"。

在laravel中发生的事情是这样的,在第一次运行调度命令后,服务器每分钟都会询问"是否有排队的作业?如果没有,则不执行任何操作。

例如,以"每日"cronjob为例。调度程序不需要知道它上次运行任务或类似内容的时间。当它遇到每日 cronjob 时,它只是检查是否是午夜。如果是午夜,它会运行作业。

另外,采取"每三十分钟"的cronjob。也许您在 10:25 注册了 cronjob。但它仍然是第一次在 10:30 运行,而不是在 10:55 运行。它不在乎您注册的时间或上次运行的时间。它只检查当前分钟是"00"还是能被 30 整除。所以在 10:30 它会运行。同样,它将在 11:00 运行。等等。

同样,默认情况下,十分钟的 cronjob 只会检查当前分钟是否可以被 10 整除。因此,无论您注册命令的时间如何,它都将仅在 XX:00、XX:10、XX:20 等上运行。

这就是为什么默认情况下它不需要存储以前运行的计划任务。但是,如果要进行监视,可以将其存储到文件中。

最新更新