Spring-使用 Quartz 和多个调度程序启动

Spring-Boot with Quartz and multiple schedulers

我正在处理这样一个场景:我们有一个具有多个模式的数据库,每个客户一个模式。这允许每个客户为他们的工作设置不同的时间表。所有模式都有相同的作业集,只是时间表不同。

我需要编写一个 Spring-Boot 应用程序以 运行 所有模式的所有作业。

这似乎可以通过为每个模式定义不同的 quartz.properties,然后为每个模式配置不同的调度程序来完成,如下所示:

@SpringBootApplication
@Configuration
public class MyApplication{

    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }

    @Bean
    public Scheduler schedulerA(Trigger trigger, JobDetail job) {
        StdSchedulerFactory factory = new StdSchedulerFactory();
        factory.initialize(new ClassPathResource("quartzA.properties").getInputStream());

        Scheduler scheduler = factory.getScheduler();
        scheduler.setJobFactory(springBeanJobFactory());
        scheduler.scheduleJob(job, trigger);

        scheduler.start();
        return scheduler;
    }

    @Bean
    public Scheduler schedulerB(Trigger trigger, JobDetail job) {
        StdSchedulerFactory factory = new StdSchedulerFactory();
        factory.initialize(new ClassPathResource("quartzB.properties").getInputStream());

        Scheduler scheduler = factory.getScheduler();
        scheduler.setJobFactory(springBeanJobFactory());
        scheduler.scheduleJob(job, trigger);

        scheduler.start();
        return scheduler;
    }    
}

我的问题是,这是正确的吗?我可以只在我的 SpringBootApplication class 中定义这些调度程序并使用 @Configuration 注释,并期望它工作(假设属性正确)吗?我错过了什么吗?

My question is, is this correct? Can I just define these schedulers in my SpringBootApplication class annotated with @Configuration

这是正确的。或者,您可以将 Spring @Schelduled 注释与属性文件中定义的 Cron 一起使用。

@Scheduled(cron = "0 15 10 15 * ?")
public void scheduleTaskUsingCronExpression() {
.
.
.

但是,如果您想要更多地控制故障转移、重试策略或跟踪等作业以及来自仪表板的 run/rerun 作业。想想spring-batch

受上述示例的启发,我找到了一种使用在应用程序属性中管理的配置的方法,这似乎更容易,并且与 Spring-Boot 应用程序的其余部分更一致。重用数据源配置特别有用。任何数量的第二类 bean 都是可能的。

@Configuration
class MainQuartzConfiguration {
    /**
     * Main scheduler bean where all jobDetails, calendars and trigger beans are attached.
     * 
     */
    @Primary @Bean
    public SchedulerFactoryBean mainScheduler(QuartzProperties properties,
            ObjectProvider<SchedulerFactoryBeanCustomizer> customizers,
            ObjectProvider<JobDetail[]> jobDetails, Map<String, Calendar> calendars,
            ObjectProvider<Trigger[]> triggers, ApplicationContext applicationContext) {
        SchedulerFactoryBean factory = new QuartzAutoConfiguration(properties, customizers, jobDetails, calendars, triggers, applicationContext)
                .quartzScheduler();
        factory.setSchedulerName("mainScheduler");
        return factory;
    }
}

@Configuration 
class AnotherConfiguration {
    /**
     * Second scheduler bean which has the same configuration but different thread count and thread priority.
     */
    
    @Bean
    SchedulerFactoryBean secondScheduler(
            QuartzProperties properties,
            ObjectProvider<SchedulerFactoryBeanCustomizer> customizers,
            @Value("${spring.quartz.properties.secondScheduler.org.quartz.threadPool.threadPriority:7}") int threadPriority,
            @Value("${spring.quartz.properties.secondScheduler.org.quartz.threadPool.threadCount:1}") int threadCount,
            ApplicationContext applicationContext)
    {
        SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
        SpringBeanJobFactory jobFactory = new SpringBeanJobFactory();
        jobFactory.setApplicationContext(applicationContext);
        schedulerFactoryBean.setJobFactory(jobFactory);
        schedulerFactoryBean.setSchedulerName("secondScheduler");
        schedulerFactoryBean.setAutoStartup(properties.isAutoStartup());
        schedulerFactoryBean
        .setStartupDelay((int) properties.getStartupDelay().getSeconds());
        schedulerFactoryBean.setWaitForJobsToCompleteOnShutdown(
                properties.isWaitForJobsToCompleteOnShutdown());
        Properties propertiesVariant = new Properties();
        propertiesVariant.putAll(properties.getProperties());
        propertiesVariant.setProperty("org.quartz.threadPool.threadPriority", Integer.toString(threadPriority));
        propertiesVariant.setProperty("org.quartz.threadPool.threadCount", Integer.toString(threadCount));
        schedulerFactoryBean.setQuartzProperties(propertiesVariant);
        schedulerFactoryBean.setJobDetails(CatalogBenchmarkJob.createJob());
        customizers.orderedStream().forEach(
                (customizer) -> customizer.customize(schedulerFactoryBean));
        return schedulerFactoryBean;
    }
}