Python 类cron循环任务调度器设计

Python 类cron循环任务调度器设计,python,cron,scheduling,Python,Cron,Scheduling,假设您希望安排定期任务,例如: 每周三上午10点发送电子邮件 在每个月的第一天创建摘要 您希望在一个web应用程序中为合理数量的用户执行此操作-即,每个用户可以决定何时计划他们想要的内容 而且你要确保计划的项目运行,即使它们最初错过了-例如,由于某种原因,电子邮件没有在周三上午10点发送,它应该在下一个检查间隔发送,比如周三上午11点 你会怎么设计呢 如果您使用cron每x分钟触发一次调度应用程序,那么实现决定在每个时间点运行什么的部分的好方法是什么 我看到的类似cron的实现比较了所有指定

假设您希望安排定期任务,例如:

  • 每周三上午10点发送电子邮件
  • 在每个月的第一天创建摘要
您希望在一个web应用程序中为合理数量的用户执行此操作-即,每个用户可以决定何时计划他们想要的内容

而且你要确保计划的项目运行,即使它们最初错过了-例如,由于某种原因,电子邮件没有在周三上午10点发送,它应该在下一个检查间隔发送,比如周三上午11点

你会怎么设计呢

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

我看到的类似cron的实现比较了所有指定项的当前时间和触发时间,但我也希望处理遗漏的项


我觉得有一个比我正在设计的更聪明的设计,所以请告诉我。

使用支持Java进程是一个可能的解决方案。我相信石英应该很好地达到这个水平。见此相关问题:

如果您仔细阅读Quartz文档,我认为您会发现您对触发和错过执行的担忧得到了清晰的处理,并提供了许多合适的策略供您选择。就可伸缩性而言,我相信您可以将作业存储在JDBC备份存储中

出局了,因为提问者特别想要一个设计讨论。。。 如果在以“Python任务调度器”的形式提问之前设置了初始StackOverflow搜索的框架,则会出现以下情况:。我强烈建议寻找一个现有的实现,而不是尝试NIH开发类似的东西,尽管在另一个答案中对如何实现这一点有着很好的观察。鉴于您声明的可伸缩性目标,您正在完成一项相当具有挑战性的任务,您应该在从头开始研究像本主题这样发展很快的主题之前,排除所有其他选项。一个可能的途径是通过Jython来适应被重视的代码>,并确定您的用例是否可以在上下文中处理,而不需要在java世界中最小化(可能不是您的首选)。
基本上有两种设计

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

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

第一种技术不能处理“遗漏”的项目,第二种技术只能处理先前计划的项目

具体来说,你有一个时间表,每小时运行一次,在最小时。

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

下午1:30,运行任务停止,不执行任何进程。直到下午3:20才重新开始

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

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

每种技术都有它的起伏。使用第一种技术,你会错过工作。使用第二种技术,你仍然可能错过工作,但它可以“赶上”(在一定程度上),但它也可能“在错误的时间”运行工作(可能出于某种原因,它应该在最高峰运行)

第二种技术的好处是,如果在执行作业结束时重新调度,则不必担心级联作业问题

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

使用第二种技术,如果您在作业结束时进行计划,那么如果一个作业恰好运行了一分钟,那么您将“跳过”一分钟并启动下一分钟,而不是在其上运行。因此,您可以将每分钟的作业计划在下午1:01、下午1:03、下午1:05等时间运行

取决于你的工作设计,这两个选项可以是“好”或“坏”。这里没有正确的答案


最后,与实现第二种技术相比,实现第一种技术确实非常简单与导出cron字符串下一个有效时间相比,匹配给定时间很简单。我知道,我有几百行代码来证明它。这并不漂亮。

如果您想跳过设计并开始使用,请看一看。调度程序称为celerybeat

编辑:
同样相关:

@Parand Quartz调度程序有内置的CronTrigger类,因此这些您想要的相当复杂的事件触发器很容易得到cron表达式的支持。感谢andersoj。我们主要基于python,我来看看是否有与Quartz相当的python。看起来APScheduler是一个受python Quartz启发的调度程序。@Paran