![]() |
1
6
基本上有两种设计。 定期运行并将当前时间与调度规范进行比较(例如,“现在运行吗?”),并执行那些符合条件的。 另一种技术采用当前的调度规范,并在下一次触发该项时找到它。然后,它将当前时间与“下一次”小于“当前时间”的所有项目进行比较,并触发这些项目。然后,当一个项目完成后,它会重新安排为新的“下一次”。 第一种技术不能处理“丢失的”项目,第二种技术只能处理那些先前计划的项目。 具体来说,考虑到你有一个每小时运行一次的时间表,在一个小时的顶部。 比如说,下午1点,2点,3点,4点。 下午1:30,运行任务关闭,不执行任何进程。直到下午3:20才重新开始。 使用第一种技术,调度程序将触发1pm任务,但不会触发2pm和3pm任务,因为这些时间过去时它没有运行。下一个要运行的作业是下午4点的作业,是的,下午4点。 使用第二种技术,调度程序将启动1pm任务,并在2pm调度下一个任务。由于系统关闭,下午2点的任务没有运行,下午3点的任务也没有运行。但是,当系统在3:20重新启动时,它发现它“错过”了下午2点的任务,并在3:20启动了它,然后又将其安排在下午4点。 每种技巧都有它的起伏。用第一种方法,你会错过工作。使用第二种技术,你仍然可以错过工作,但它可以“赶上”(某一点),但它也可能“在错误的时间”运行一个工作(可能出于某种原因,它应该在最高峰时间运行)。 第二种技术的一个好处是,如果在执行作业结束时重新计划,就不必担心级联作业问题。 想想你有一份每分钟都在运行的工作。用第一种方法,工作每分钟都会被解雇。但是,通常情况下,如果作业在几分钟内没有完成,那么您可能有两个作业正在运行(一个在进程后期,另一个在启动)。如果作业设计为不同时运行一次以上,则这可能是一个问题。而且这种情况会恶化(如果真的有问题,10分钟后,你就有10份工作,所有的工作都在互相竞争)。 使用第二种技术,如果您在作业结束时调度,那么如果一个作业刚好运行超过一分钟,那么您将“跳过”一分钟并启动下一分钟,而不是在其上运行。所以,你可以把每分钟的作业安排在下午1:01、1:03、1:05等等。 根据你的工作设计,这两者中的任何一个都可以是“好”或“坏”。这里没有正确的答案。 最后,与实现第二种技术相比,实现第一种技术确实是非常微不足道的。与派生cron字符串下一个有效时间相比,确定cron字符串是否匹配给定时间的代码很简单。我知道,我有几百行代码可以证明这一点。它不漂亮。 |
![]() |
2
4
如果你想跳过设计,开始使用,看看芹菜。 http://celeryproject.org/ . 调度程序称为celerybeat。 编辑: 也相关: How to send 100,000 emails weekly? |
![]() |
3
2
使用支持的Java进程 Quartz scheduler 可能是一个潜在的解决方案。我相信石英应该能很好地达到这个水平。请参阅相关的SO问题: "How to scale the Quartz Scheduler" … 如果您仔细查看Quartz文档,我想您会发现,您对触发和错过执行的担忧得到了清晰的处理,并提供了一些合适的策略供您选择。在可伸缩性方面,我相信您可以将作业存储在JDBC后备存储中。
出其不意,因为发问者是专门寻找一个设计讨论…
|
![]() |
prmph · javascript上抢占式后台工作调度的通用解决方案 7 年前 |
![]() |
Terry Pang · 当涉及多个通道时,select如何工作? 7 年前 |
![]() |
martine · 索引器:索引2超出大小为2的轴0的界限(列表调度) 7 年前 |
![]() |
user2887596 · scala中长时间间隔的任务调度 7 年前 |
|
Kevin SUN · 具有实时任务的多核Linux软锁定 8 年前 |
![]() |
Mounhim · Quartz.net的日常工作每分钟都在执行 11 年前 |