作业调度程序的轮询替代方案

本文关键字:方案 调度程序 作业 | 更新日期: 2023-09-27 17:58:27

我们在工作中需要一个作业服务器,我目前正在使用Quartz.net,但创建自己的想法对我很有吸引力。至少了解Quartz.net可能在做什么不会影响我的理解/更有效地使用它的机会。

所以我的问题是,你会如何在没有投票的线程上获得和解雇工作?如果你每隔2分钟检查一下你的"jobstore"是否有需要解雇的工作,你可能会有大约2分钟的延迟。如果你减少了投票时间,你的工作就会增加压力,但仍然没有真正的开始时间。你可以为接下来的两分钟段预加载作业,并在剩余的时间内让线程休眠,以便它们在适当的时间开始,但如果你的轮询时间很长(删除、重新安排等),这似乎很草率,很容易出现问题。我正在删除Quartz来弄清楚它是如何做到的,但我想知道我是否错过了一些基本的东西。

编辑:

Kevin最初描述的线程结构似乎是你应该如何做作业服务器的。它以最少的开销为您提供最大的灵活性。因为线程对大多数人来说都是一个皮塔(也许只有我:),所以更简单的轮询示例将在90%的情况下完成任务,代价是失去灵活性和更多的开销。

另一方面,除非你用一个正在执行的作业来实现单线程,否则你无论如何都必须处理线程。不妨全力以赴,找出信号。

我也同意Kevin的观点,你声称你在民意调查数据库示例中免费获得的东西并不是真正免费的。你会像编写线程/等待应用程序一样编写代码。如果您的轮询数据库作业服务器在作业中间爆炸了怎么办?两者都将依靠一些耐用的存储来跟踪他们的状态,以防发生灾难。

如果您将"jobstore"提升到一个抽象级别,而它不是基于普通的ACID(正确的术语?)数据库,该怎么办。现在,我相信你的很多"免费"东西所基于的东西已经不可用了(交易?)。

作业调度程序的轮询替代方案

您将创建一个按时间(最短到最长时间)排序的要启动的任务队列。正好有一个线程在队列的头部等待时间。当该时间到期时,您将删除该项目并启动任务。如果是重复任务,请重新计算并放回队列。

唯一棘手的是线程应该根据一些条件变量进行等待。如果队列头发生变化,则可以用信号通知条件变量。通常使用条件变量,您可以判断它是否已发出信号,以及超时是否已过期。因此,如果发出信号,您只需重新等待新的头时间,否则超时表示是时候在队列的头运行任务了。

这个解决方案意味着您只有一个线程来管理任务,而不是轮询。

编辑:

我将更新我的解决方案,指出编写自己的调度程序可能不是一个好主意,因为石英是一个非常好的解决方案。此外,我认为每秒的民意调查有点过头了,因为工作通常是按分钟进行的,而不是按秒进行的。例如,你真的在乎一份工作是在12:00:05开始,还是12:00:00就足够了?无论如何,您都可以将轮询参数化,以满足所需的粒度级别。