6

我们使用 Quartz.Net 来安排大约 200 个重复作业。每个作业使用相同的 IJob 实现类,但它们可以有不同的时间表。在实践中,他们最终有相同的时间表,所以我们有大约 200 个工作细节,每个都有自己的(相同的)重复/简单触发器,计划。间隔为一小时。

此作业执行的任务是下载 rss 提要,然后下载链接到 rss 提要中的所有媒体文件。在下载之前,它会擦除​​要放置文件的目录。一个作业的单次运行需要几秒钟到十几秒钟(有时更多)。

我们的调度方法是在一个新的 StdSchedulerFactory 上调用 GetScheduler()(所有作业都被同时调度到同一个 IScheduler 实例中)。我们使用立即 Start() 来遵循调度。

这些作业似乎运行良好,但经过仔细检查,我们发现少数作业偶尔 - 或几乎从未 - 运行。

因此,例如,所有 200 个作业应该在今晚 6:40 pm 运行。他们中的大多数人都这样做了。但少数没有。我通过查看文件时间戳来确定这一点,如果作业运行,肯定应该更新(因为它会删除并重新下载文件)。

我启用了 Quartz.Net 日志记录,并在我们的代码中添加了很多日志记录语句。

我收到日志消息,表明 Quartz 在一轮作业开始后大约一分钟内创建和执行作业。

之后,所有活动停止。没有作业运行,也没有创建日志消息。零。

然后,在下一个触发间隔,Quartz 再次启动,我的日志文件更新,各种文件开始下载。但是 - 它肯定看起来像一些 JobDetail 实例永远不会排在行首(可以这么说)或者很少这样做。在整个周末,一些作业似乎更新得相当频繁,最近,还有一些作业自周五启动该过程以来一次没有更新(它在 Windows 服务 shell 中运行,顺便说一句)。

所以......我希望有人能帮助我理解石英的这种行为。

我需要确定每项工​​作都能运行。如果错过了触发器,我需要 Quartz 尽快运行它。通过阅读文档,我认为这将是默认行为 - 对于具有无限重复计数的 SimpleTrigger,如果错过了触发窗口,它将重新安排作业以立即执行。情况似乎并非如此。有什么方法可以确定为什么 Quartz 没有解雇这些工作?我在跟踪级别记录,他们只是不在那里。它创建并执行了大量的工作,但如果我发现一个缺失 - 我只能找到它最后一次运行它(例如,有时它没有运行几个小时或几天)。没有任何关于它被跳过的原因(我希望 Quartz 会记录一些东西,如果它因为任何原因跳过工作)等等。

任何帮助都会非常非常感激 - 我花了一整天的时间来解决这个问题。

4

1 回答 1

3

阅读您的帖子后,听起来很像少数未执行的作业很可能会失败。我相信这一点的原因:

我收到日志消息,表明 Quartz 在一轮作业开始后大约一分钟内创建和执行作业。

在 Quartz.NET 中,默认的失火阈值为 1 分钟。很有可能,您需要检查您的日志记录配置以确定为什么没有记录这些失火事件。我敢打赌,如果您打开日志记录的闸门(即,将所有内容设置为调试,并确保您肯定有 Quartz 调度程序类的日志记录指令),然后重新运行您的作业。我几乎可以肯定,问题在于您的日志中没有显示失火事件,因为日志配置缺少某些内容。这是可以理解的,因为日志配置会很快变得非常混乱。

此外,将来,您可能想咨询谷歌上的quartz.net 论坛,因为那里讨论了一些更棘手的问题。

http://groups.google.com/group/quartznet?pli=1

现在,您关于设置调度程序应该做什么的策略的其他问题,我不能在那里专门为您提供帮助,但是如果您仔细阅读 API 文档,并咨询 google 讨论组,您应该能够轻松设置适合您需求的失火政策标志。我相信触发器有一个 MisfireInstruction 属性,您可以配置它。

另外,我认为失火会带来很多“噪音”,应该避免;也许增加调度程序的线程数是避免失火的一种方法?另一种选择是将您的作业执行错开成单独/多个批次。

祝你好运!

于 2010-07-26T23:53:12.733 回答