Quartz重试作业具有指数增加的触发延迟时间策略

问题描述 投票:0回答:2

我在春季项目中使用石英。我们的想法是为新的收入数据创建单独的工作,这些工作未成功交付给目标服务。

  • 为了以指数级增长的策略提供数据,我也为下次不成功的尝试创建了工作。 (它垃圾邮件DB。看起来很有效,但可以更好。)
  • 不同我的解决方案是创建可重复的基于crone的作业,扫描DB数据和加载只应该处理日期,因为时间过去了(在这种情况下我必须在java部分管理很多)。

两种方式都可以提供正确的流量,但我更喜欢盒式解决方案。

我试图管理触发工作的JobExecutionContext使用相同的JobDetailquartzScheduler注册它。我们的想法是用不同的触发器更新现有作业。但问题是石英试图在DB中创建新的工作。

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$2.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]

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

  • 如何通过石英作业触发器更新进行管理(如果未成功处理 - 使用不同的触发时间更新触发器)?
  • 如何通过石英作业更新进行管理(如果未成功处理 - 使用新触发器更新作业)?
  • 如何为触发器注册指数增加的延迟时间策略?
java quartz-scheduler quartz
2个回答
1
投票
  • 你可以遵循这种方法(重试机制,并且可以不允许重试)ref:Quartz retry when failure
  • 对于每次失败,您都可以更新计数器并发送电子邮件。因此,您将在最大尝试中意识到它是否成功通过。
  • 如果不是以后,您将有一个仪表板来查看失败(包括其尝试的次数)并可以手动运行它。
  • 您可以设置时间轴ex,而不是e.setRefireImmediately。 120分钟后,计划运行它,即基于JobDataMap机制

1
投票

简单的答案是:

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

详细的答案是:

  • 如何通过石英作业触发器更新进行管理

scheduler.rescheduleJob(trigger.getKey(),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);
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.