类似cron的重复任务调度程序设计

时间:2010-10-20 17:50:02

标签: python cron scheduling

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

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

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

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

你会如何设计?

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

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

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

3 个答案:

答案 0 :(得分:6)

基本上有两种设计。

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

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

第一种技术无法处理“遗漏”物品,第二种技术只能处理之前预定的物品。

特别考虑到你有一个每小时运行一次的时间表,在一小时之内。

所以,比方说,下午1点,下午2点,下午3点,下午4点。

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

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

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

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

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

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

使用第二种技术,如果你在工作结束时安排,那么如果一项工作恰好在一分钟内运行,那么你将“跳过”一分钟“然后启动下一分钟而不是继续运行因此,你可以在下午1点01分,下午1点03分,下午1点05分等实际运行的每一分钟安排一份工作。

根据您的工作设计,其中任何一个都可能是“好”或“坏”。这里没有正确答案。

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

答案 1 :(得分:4)

如果您想跳过设计并开始使用,请查看芹菜http://celeryproject.org/。调度程序称为celerybeat。

编辑: 相关:How to send 100,000 emails weekly?

答案 2 :(得分:2)

使用Quartz scheduler支持Java流程可能是一种潜在的解决方案。我相信Quartz应该能够很好地扩展到这个水平。请参阅此相关的SO问题:"How to scale the Quartz Scheduler" ...

如果您仔细查看Quartz文档,我认为您会发现您对触发和错过执行的担忧得到了彻底解决,并提供了许多合适的策略供您选择。在可伸缩性方面,我相信您可以将作业存储在JDBC后备存储中。

开始了,因为提问者专门寻找设计讨论... <击> 如果您在根据“Python的任务调度程序”提问之前构建了初始的StackOverflow搜索,那么您可以将其调高:"An enterprise scheduler for python..."。我强烈建议寻找一个现有的实现,而不是尝试NIH开发这样的事情,尽管在另一个答案中你可能会如何做到这一点。鉴于您所述的可扩展性目标,您正在寻找一项相当具有挑战性的任务,并且您应该先消除所有其他选项,然后再深入研究与此相关的主题。一个可能的考虑途径是通过Jython适应备受好评的Quartz,并确定是否可以在该上下文中处理您的用例,同时尽可能少地进入Java世界(可能不是您的首选)。