SpringBoot|SpringBoot 如何配置 quartz 为分布式定时任务
SpringBoot 如何配置 quartz 为分布式定时任务
首发于 Dale’s blog
背景
项目需要一个分布式的定时任务,预研之后选择使用 quartz
。quartz
的分布式需要依赖关系型数据库支持存储一些任务信息。建表sql存在于 quartz
项目中,github 可见
库中提供了多种数据库的执行sql,我的项目采用的 postgres
作为持久化数据库。
配置 quartz
QuartzJobFactory
/**
* quartz job factory
*
* @author Dale
*/
@Component
public class QuartzJobFactory extends AdaptableJobFactory {@Autowired
private AutowireCapableBeanFactory autowireCapableBeanFactory;
@Override
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
Object jobInstance = super.createJobInstance(bundle);
autowireCapableBeanFactory.autowireBean(jobInstance);
return jobInstance;
}
}
QuartzConf
/**
* 配置分布式 quartz
*
* @author Dale
*/
@Configuration
public class QuartzConf {private QuartzJobFactory quartzJobFactory;
@Resource(name = "master")
private DataSourceProperties masterProperties;
@Autowired
public void setQuartzJobFactory(QuartzJobFactory quartzJobFactory) {
this.quartzJobFactory = quartzJobFactory;
}@Bean
public SchedulerFactoryBean schedulerFactoryBean() throws IOException {
PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
// 设置 quartz 的配置文件是 classpath 下的 quartz.properties 文件
propertiesFactoryBean.setLocation(new ClassPathResource("quartz.properties"));
propertiesFactoryBean.afterPropertiesSet();
SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
schedulerFactoryBean.setQuartzProperties(Objects.requireNonNull(propertiesFactoryBean.getObject()));
schedulerFactoryBean.setJobFactory(quartzJobFactory);
schedulerFactoryBean.setApplicationContextSchedulerContextKey("applicationContextKey");
schedulerFactoryBean.setWaitForJobsToCompleteOnShutdown(true);
schedulerFactoryBean.setOverwriteExistingJobs(false);
schedulerFactoryBean.setStartupDelay(10);
// 设置 quartz 的DataSource 为主库的配置
schedulerFactoryBean.setDataSource(masterProperties.initializeDataSourceBuilder().type(DruidDataSource.class).build());
return schedulerFactoryBean;
}@Bean(name = "scheduler")
public Scheduler scheduler() throws IOException {
return schedulerFactoryBean().getScheduler();
}}
注意:由于项目先前配置了数据库的主从分离,所以公用数据库链接,避免额外再有一处数据库连接配置。quartz.properties
org.quartz.scheduler.instanceName=liveScheduler
org.quartz.scheduler.instanceId=AUTOorg.quartz.jobStore.useProperties=true
org.quartz.jobStore.isClustered=true
# 由于使用 postgres,quartz 的表并不是建在 publish schema 下,所以需要在 tablePrefix 设置schema的名字
org.quartz.jobStore.tablePrefix=quartz.qrtz_
org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
使用 先定义一个 job
@Repository
public class LotteryJobs implements Job {@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
// todo::
}}
【SpringBoot|SpringBoot 如何配置 quartz 为分布式定时任务】然后调用
JobDetail jobDetail = JobBuilder.newJob(LotteryJobs.class).withIdentity("lottery-" + lotteryEntity.getId()).build();
jobDetail.getJobDataMap().put("lotteryId","");
jobDetail.getJobDataMap().put("roomId", "");
Trigger trigger = TriggerBuilder.newTrigger().withIdentity("lottery-" + lotteryEntity.getId()).startAt(getLotteryTime()).build();
try {
scheduler.scheduleJob(jobDetail, trigger);
} catch (SchedulerException e) {
LOGGER.error("lottery schedule create error,lotteryId:" + lotteryEntity.getId(), e);
throw new BusinessException(ApiCode.ERROR);
}
推荐阅读
- 考研英语阅读终极解决方案——阅读理解如何巧拿高分
- 如何寻找情感问答App的分析切入点
- vue-cli|vue-cli 3.x vue.config.js 配置
- Activiti(一)SpringBoot2集成Activiti6
- mybatisplus如何在xml的连表查询中使用queryWrapper
- MybatisPlus使用queryWrapper如何实现复杂查询
- SpringBoot调用公共模块的自定义注解失效的解决
- 解决SpringBoot引用别的模块无法注入的问题
- 如何在Mac中的文件选择框中打开系统隐藏文件夹
- 漫画初学者如何学习漫画背景的透视画法(这篇教程请收藏好了!)