python - 类似 cron 的循环任务调度程序设计

标签 python cron scheduling

假设您想安排重复性任务,例如:

  • 每周三上午 10 点发送电子邮件
  • 在每个月的第一天创建摘要

并且您想在 Web 应用程序中为合理数量的用户执行此操作 - 即。 10 万个用户,每个用户可以决定他们想要什么时间安排。

并且您希望确保计划的项目运行,即使它们最初被错过 - 例如。由于某种原因,电子邮件没有在星期三上午 10 点发送,它应该在下一个检查时间间隔发送,比如星期三上午 11 点。

你会如何设计?

如果您使用 cron 每 x 分钟触发您的日程安排应用程序,那么实现决定在每个时间点应该运行什么的部分的好方法是什么?

我见过的类似 cron 的实现将当前时间与所有指定项目的触发时间进行比较,但我也想处理遗漏的项目。

我觉得有比我正在设计的设计更聪明的设计,所以请赐教。

最佳答案

基本上有 2 种设计。

定期运行并将当前时间与调度规范进行比较(即“现在运行吗?”),然后执行符合条件的。

另一种技术采用当前调度规范并找到该项目应触发的下一次时间。然后,它将当前时间与所有那些“下一次”时间小于“当前时间”的项目进行比较,并触发这些项目。然后,当一个项目完成时,将重新安排新的“下一次”。

第一种技术无法处理“错过”的项目,第二种技术只能处理那些先前安排好的项目。

具体考虑您有一个每小时运行一次的计划。

比如说,下午 1 点、2 点、3 点、4 点。

下午 1 点 30 分,运行任务已关闭且未执行任何进程。直到下午 3:20 才重新开始。

使用第一种技术,调度程序将触发下午 1 点的任务,但不会触发下午 2 点和 3 点的任务,因为在这些时间过去时它没有运行。下一个要运行的作业是下午 4 点的作业,嗯,就是下午 4 点。

使用第二种技术,调度程序将触发下午 1 点的任务,并在下午 2 点安排下一个任务。由于系统宕机,下午 2 点的任务没有运行,下午 3 点的任务也没有运行。但是当系统在 3:20 重新启动时,它看到它“错过”了下午 2 点的任务,并在 3:20 将其关闭,然后再次安排到下午 4 点。

每种技术都有其优缺点。使用第一种技术,你会错过工作。使用第二种技术,您仍然可以错过作业,但它可以“ catch ”(在一定程度上),但它也可能“在错误的时间”运行作业(也许它应该在整点运行一段时间原因)。

第二种技术的好处是,如果您在执行作业的末尾重新安排,则不必担心级联作业问题。

假设您有一个每分钟都在运行的作业。使用第一种技术,工作每分钟都会被解雇。但是,通常情况下,如果作业没有在一分钟内完成,那么您可能有 2 个作业正在运行(一个在流程后期,另一个在启动)。如果作业未设计为同时运行多次,则这可能是个问题。而且它可能会加剧(如果有真正的问题,10 分钟后您将有 10 个工作互相争斗)。

使用第二种技术,如果您在作业结束时安排,那么如果作业刚好运行一分钟多一点,那么您将“跳过”一分钟”并在下一分钟开始运行,而不是继续运行自己的顶部。因此,您可以为实际在下午 1:01、1:03、1:05 等运行的每一分钟安排一个作业。

根据您的工作设计,这些可能是“好”或“坏”。这里没有正确答案。

最后,与实现第二种技术相比,实现第一种技术确实非常简单。与推导一个 cron 字符串何时有效 NEXT 相比,确定一个 cron 字符串(比如说)是否匹配给定时间的代码很简单。我知道,我有几百行代码来证明这一点。它不漂亮。

关于python - 类似 cron 的循环任务调度程序设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3980782/

相关文章:

php - 如何在 Ubuntu 操作系统上使用 cron 作业每天运行 php 脚本

python - 无法使用 python 3.5 安装 opencv 3.1,仅适用于 2.7

php - 包括一个 .py 文件,仍然不会破坏 cronjob(Python,初学者)?

python - 无法在 crontab Mac OS 中导入 mysql-python

Java、线程和优先级

operating-system - FreeRTOS 初始上下文切换

c - 循环线程访问 pthread mutex

Python开发模块路径

python - 移动 numpy 数组列和行?

python - 按月份名称和年份对 groupby pandas 输出进​​行排序