前言
对于简单的任务处理可以用Spring的@Scheduled
如果处理更复杂的情况,比如需要宕机恢复或者集群调度,那么Quartz是个不错的轻量级方案。
Quartz的模块
image.png
SchedulerFactory
SchedulerFactory负责初始化,读取配置文件,然后创建Scheduler
Scheduler
是中枢调度器,负责管理Trigger/JobDetail和3个调度线程
JobDetail
保存Job的元信息,包括类定义和设置。
Trigger
定义了何时触发任务,主要是两种SimpleTrigger和CronTigger,其他Tigger基本都可以通过这两种实现。Trigger还可以定义错过的任务如何处理。下表是说明:
image.png
Calendar
Calendar与Trigger相反,定义哪些时间是特例,不能执行任务。Calendar的优先级高于Trigger。
Job
负责定义任务所处理的逻辑,实现类需要实现org.quartz.Job接口
public interface Job {
void execute(JobExecutionContext context) throws JobExecutionException;
}
JobDetail
保存Job的元信息,包括类定义和设置
QuartzSchedulerThread
主调度线程
image.png
MisfireHandler
错失触发的任务恢复线程,。更新Trigger的触发时间。
ClusterManager
集群协调线程。定期心跳,自动recover。同主程序中的recover。
示例
引入Maven依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
编写具体的job
public class TestJob extends QuartzJobBean {
@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
System.out.println("Test job executed.");
}
}
定义JobDetail, 把Job的class类型传入。Spring自动处理
@Bean
public JobDetail testJob(){
return JobBuilder
.newJob(TestJob.class)
.withIdentity("TestJob")
.storeDurably()
.requestRecovery()
.build();
}
定义Trigger, 通过Key关联JobDetail。Spring 自动处理。
@Bean
public Trigger testTrigger(){
return TriggerBuilder.newTrigger()
.withIdentity("TestTrigger")
.forJob("TestJob")
.withSchedule(CronScheduleBuilder
.cronSchedule("0/6 * * * * ? ")
.withMisfireHandlingInstructionDoNothing())
.build();
}
如果需要不同的数据库,定义一个@Primary主库,和一个@QuartzDataSource quartz专用库
@Bean
@Primary
@ConfigurationProperties(prefix="spring.datasource")
public DataSource primaryDataSource() {
return DataSourceBuilder.create().build();
}
@Bean
@QuartzDataSource
@ConfigurationProperties(prefix="spring.datasource.quartz")
public DataSource quartzDataSource() {
return DataSourceBuilder.create().build();
}
application.properties 都有默认配置,第一行启用数据库,后面两行是cluster功能
spring.quartz.job-store-type=jdbc
spring.quartz.org.quartz.scheduler.instanceId = AUTO
spring.quartz.org.quartz.jobStore.isClustered = true
虽然Spring提供了自动建库的功能,但是第一次建完之后需要改成never
spring.quartz.jdbc.initializeSchema=ALWAYS
#spring.quartz.jdbc.initializeSchema=NEVER
网友评论