3

我正在寻找一种以编程方式模拟或强制触发器失火的方法。这是场景:

我有一个要触发的作业,但该作业需要一些有时可能不可用的底层资源。如果资源不可用,我希望 Quartz 稍后根据失火策略重新触发触发器。

我已经探索了两个相似但不完全是我正在寻找的选项:

  1. 抛出 JobExecutionException 并将 refireImmediately 设置为 true:有效,但不会根据失火策略延迟执行;这会影响资源可用性检查。
  2. 在未来某个固定的时间间隔安排第二个触发器:也有效,但不考虑失火策略。这意味着一项作业可能会因不同的失败运行而排队等待大量重试。

有什么想法或我想念的任何东西吗?谢谢!

4

1 回答 1

0

如果我做对了,您就不需要强制或模拟失火,因为资源可用性是“您的工作可以处理的东西”

Misfires存在并由 Quartz 管理,用于处理服务器关闭或其他阻止 Job 执行的“意外问题”等情况。

您有两个选项可以实现简单的容错重试逻辑;只有当底层资源可用时,您的 Job 才能执行其逻辑,因此您可以:

  1. 等待资源可用:
    • 在这种情况下,您的作业会等待并重复检查资源可用性,最终在短暂超时后,作业可以放弃并结束。

  2. 如果资源不可用,什么都不做:
    • 在这种情况下,作业结束而不做任何事情,它将正常触发并根据触发器定义重试。

在这两种情况下,如果资源可用,作业可以执行其内部逻辑并使用底层资源。(没有失火,因为 Job 已实际执行)

这可以使用触发器来完成,设置您需要的失火策略,以防作业根本无法执行。请参阅这篇关于 Quartz misfires的精彩而详细的文章。


在您的情况下,如果您想每天执行一次作业:

  1. 定义一个 Cron 触发器,该触发器在一天内在给定的时间跨度内触发多次,例如,从上午 8:00 到上午 12:00 每 15 分钟触发一次:

    0 0/15 8-12 * * ?
    
  2. 构建使用上述两种方法之一的作业

  3. 您的 Job 内部逻辑第一次执行(即资源可用)时,您的 Job 将在 DB 上的某处保存一个“作业执行标志”和执行日期。

在以下触发器执行中,作业将检查标志并且不会再次执行其内部逻辑。


此外,如果您的作业需要很长时间才能完成,您可能希望在作业实现上使用以下注释来防止同一作业的并发执行:

@DisableConcurrentExecution

有关作业执行的更多信息,请参阅 Quartz教程

于 2013-09-24T15:17:24.870 回答