假设您想安排重复性任务,例如:
- 每周三上午 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/