Quartz 重试作业,触发器的延迟时间策略呈指数增长

Quartz retry job with exponentially increasing delay time strategy for trigger

我在 spring 项目中使用石英。这个想法是为新的收入数据创建单独的作业,这些数据没有成功传送到目标服务。

两种方式都可以提供正确的流程,但我更喜欢开箱即用的解决方案。

我尝试管理 JobExecutionContext 触发作业以使用相同的 JobDetailquartzScheduler 中注册它。这个想法是用不同的触发器更新现有的工作。但问题是 quartz 试图创建新的工作并将其持久保存在数据库中。

org.quartz.ObjectAlreadyExistsException: Unable to store Job : 'digex-caas-securepay.b333e5bf-583f-4643-9ad7-ef4b913001f7', because one already exists with this identification.
    at org.quartz.impl.jdbcjobstore.JobStoreSupport.storeJob(JobStoreSupport.java:1113) ~[quartz-2.3.0.jar:na]
    at org.quartz.impl.jdbcjobstore.JobStoreSupport.executeVoid(JobStoreSupport.java:1067) ~[quartz-2.3.0.jar:na]
    at org.quartz.impl.jdbcjobstore.JobStoreSupport$VoidTransactionCallback.execute(JobStoreSupport.java:3765) ~[quartz-2.3.0.jar:na]
    at org.quartz.impl.jdbcjobstore.JobStoreSupport$VoidTransactionCallback.execute(JobStoreSupport.java:3763) ~[quartz-2.3.0.jar:na]
    at org.quartz.impl.jdbcjobstore.JobStoreCMT.executeInLock(JobStoreCMT.java:245) ~[quartz-2.3.0.jar:na]
    at org.quartz.impl.jdbcjobstore.JobStoreSupport.storeJobAndTrigger(JobStoreSupport.java:1063) ~[quartz-2.3.0.jar:na]
    at org.quartz.core.QuartzScheduler.scheduleJob(QuartzScheduler.java:855) ~[quartz-2.3.0.jar:na]
    at org.quartz.impl.StdScheduler.scheduleJob(StdScheduler.java:249) ~[quartz-2.3.0.jar:na]
    at com.incomm.ecomm.services.quartz.OrderQuartzJobScheduler.registerSecurePayPostServiceJob(OrderQuartzJobScheduler.java:59) ~[classes/:na]

问题是(请回答任何一个):

  • 你可以按照这个方法(重试机制,可以没有。 允许重试)参考: Quartz retry when failure
  • 对于每次失败,您都可以更新计数器并发送电子邮件。那么你 在最大尝试中也会知道它是否成功通过。
  • 如果不是稍后,您将有一个仪表板来查看失败的(包括 no.of 次尝试)并且可以 运行 手动机制。
  • 您可以设置时间线,而不是 e.setRefireImmediately。 120 分钟后,调度到 运行 它即基于 JobDataMap 机制

简单的答案是:

scheduler.rescheduleJob(trigger.getKey(), trigger);

详细答案是:

  • How to manage via quartz job trigger updates

scheduler.rescheduleJob(trigger.getKey(), 触发器);

  • How to manage via quartz job updates

万一更新触发器就不再重要了。

  • How to register exponentially increasing delay time strategy for trigger?

单个触发器可以重新安排任何不同的时间。可以使用 IntervalCalculationStrategy.

的任何实现来计算下一次执行的时间

重新安排作业的示例:

可以从JobExecutionContext获取工作和工作详细信息,但不是必需的。触发器只能连接到一个作业,所以它足以让石英指定 triggerKey 更新:

@Autowired
private Scheduler scheduler;
@Autowired
private IntervalCalculationStrategy intervalCalculation;

public <T extends QuartzJobBean> void registerSecurePayPostServiceJob(
    JobExecutionContext firedJobExecutionContext) {
  Optional<SimpleTriggerImpl> mutableTrigger =
      ofNullable(firedJobExecutionContext)
          .map(JobExecutionContext::getTrigger)
          .filter(SimpleTriggerImpl.class::isInstance)
          .map(SimpleTriggerImpl.class::cast);
  try {
    if (mutableTrigger.isPresent()) {
      SimpleTriggerImpl trigger = mutableTrigger.get();
      int nextAttemptNumber = trigger.getTimesTriggered();
      log.trace("trigger: {} fired [{}] times", trigger.getFullName(),
          trigger.getTimesTriggered());
      trigger.setStartTime(intervalCalculation.calculateNextTryDate(nextAttemptNumber));
      this.scheduler.rescheduleJob(trigger.getKey(), trigger);
    }
  } catch (SchedulerException e) {
    log.error("job was not rescheduled <{}>", firedJobExecutionContext.getJobDetail(), e);
  }
}