Quartz 初使用
背景:
需要创建一个单机Schedule Service,可让用户配置定时任务,定时执行相应功能,并且确保在服务重启后添加的定时任务仍然可以运行,基于JDK 8、spring-boot 2.2.5、 spring-boot-starter-quartz 2.2.5。
实现方案:
- Java ScheduledExecutorService 可以实现基于时间点重复执行某个任务,但是不支持任务表达式,也不能动态修改定时任务。
ScheduledExecutorService scheduledService = Executors.newScheduledThreadPool(3);
scheduledService.scheduleAtFixedRate(() -> System.out.println("runnable task."), 100, 100, TimeUnit.MILLISECONDS);
- Spring ThreadPoolTaskScheduler 可以基于时间点重复执行,也可以基于Cron 表达式执行,但是无法动态修改定时任务。
ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
Trigger trigger = new CronTrigger("* 0/2 * * * ?");
threadPoolTaskScheduler.schedule(() -> System.out.println("runnable task."), trigger);
- Quartz 可以基于时间点、也可以基于Cron表达式,并且可以运行期间动态修改定时任务。
JobKey jobKey = JobKey.jobKey("KEY_NAME", "KEY_GROUP");
JobDetail jobDetail = JobBuilder.newJob(EsCompareJob.class).withIdentity(jobKey).build();
CronTrigger cronTrigger = TriggerBuilder.newTrigger().withSchedule(CronScheduleBuilder.cronSchedule(scheduleTaskVO.getScheduleCron())).startNow().build();
scheduler.scheduleJob(jobDetail, cronTrigger);
基于上述分析,选择了Quartz作为最终实现。
Quartz 核心API:
Scheduler
– 任务调度器,可以增加、删除和列举Job和Trigger, 可在classpath下添加quartz.properties进行自定义配置,未配置则使用默认配置。
Job
– 需要执行的任务
JobDetail
– 定义Job的实例,可配置一些属性,如jobKey和jobDataMap。
Trigger
– 触发任务的时机配置,包括通过时间点的SimpleTriggger
和 Cron表达式的CronTrigger
代码实现:
Demo Job,需要执行的任务
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
public class DemoJob implements Job {
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
// Object jobData = jobDataMap.get("jobData");
System.out.println("run the demo task.");
}
}
构建触发器,将触发器和任务加入调度器执行:
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
public class DemoScheduleService {
private final Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
public DemoScheduleService() throws SchedulerException {
}
public void triggerDemoTask() throws SchedulerException {
JobKey jobKey = JobKey.jobKey("demoKey", "demoGroup");
JobDetail jobDetail = JobBuilder.newJob(DemoJob.class).withIdentity(jobKey).build();
jobDetail.getJobDataMap().put("demo", new Object());
CronTrigger cronTrigger = TriggerBuilder.newTrigger().withSchedule(CronScheduleBuilder.cronSchedule("* 0/2 * * * ?")).build();
scheduler.scheduleJob(jobDetail, cronTrigger);
// scheduler.deleteJob(jobKey);
}
}