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;
}
}
我正在处理这样一个场景:我们有一个具有多个模式的数据库,每个客户一个模式。这允许每个客户为他们的工作设置不同的时间表。所有模式都有相同的作业集,只是时间表不同。
我需要编写一个 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;
}
}