Quartz 集群 - @DisallowConcurrentExecution 避免跨实例并行运行

Ket*_*tan 5 java quartz-scheduler spring-scheduled spring-boot

我有 springBoot 应用程序在多个实例中运行 Quarts (2.3.0),集群模式为 true 。

我已经配置了作业并在每次运行之间提供了 2 秒的延迟。

@Configuration
public class SchedulerConfig {


  @Bean
  public JobDetail jobDetail() {
    return JobBuilder.newJob()
            .ofType(BatchTriggerJob.class)
            .storeDurably()
            .withIdentity("SCHEDULER")
            .withDescription("event")
            .build();
  }

  @Bean
  public Trigger trigger() {
    return TriggerBuilder
            .newTrigger()
            .forJob(jobDetail())
            .withIdentity("BATCH")
            .withDescription("SCHEDULER")
            .withSchedule(SimpleScheduleBuilder.simpleSchedule().repeatForever().withIntervalInSeconds(2)
                    .withMisfireHandlingInstructionIgnoreMisfires())
            .build();
  }

}
Run Code Online (Sandbox Code Playgroud)

我已启用 DisallowConcurrentExecution

@DisallowConcurrentExecution
public class BatchTriggerJob extends QuartzJobBean {

  @Autowired
  private SchedulerService schedulerService;

  @Override
  protected void executeInternal(JobExecutionContext context) {
    SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
    schedulerService.processBatch(); //business logic and may take more than 2 sec
  }

}
Run Code Online (Sandbox Code Playgroud)

应用程序.yml

quartz:
    job-store-type: jdbc
    jdbc:
      initialize-schema: always
    properties:
      org:
        quartz:
          scheduler:
            instanceName: EVENT_SCHEDULER
            instanceId: AUTO
          jobStore:
            isClustered: true
            misfireThreshold: 60000
            class: org.quartz.impl.jdbcjobstore.JobStoreTX
            driverDelegateClass: org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
            tablePrefix: QRTZ_
          threadPool:
            threadCount: 1
Run Code Online (Sandbox Code Playgroud)

但是,如果作业处理时间超过 2 秒,则另一个实例将开始执行作业。

我希望在集群模式开启的情况下跨实例顺序执行,并且仅当当前作业在另一个实例中完成时才跨实例启动另一个作业。

PS:对于单节点,即使延迟小于处理时间。由于@DisallowConcurrentExecution,作业正在顺序运行

Mat*_*fek 0

以下是 Quartz 可能忽略的一些可能原因@DisallowConcurrentExecution

  • Quartz 属性org.quartz.jobStore.isClustered未设置为true

    true不是 Spring-Boot 中的默认值!您必须提供此石英属性。例如,通过application.properties:

    spring.quartz.properties.org.quartz.jobStore.isClustered=true
    
    Run Code Online (Sandbox Code Playgroud)
  • 如果您通过标准 Spring 集成创建作业,元数据将仅在 QRTZ_JOB_DETAILS 中存储一次。如果稍后添加注释,则IS_NONCONCURRENT不会更新。