BaseCalendar
专门用于屏蔽一个时间区间,使Trigger在这个区间中不被触发
AnnualCalendar
排除每一年中指定的一天或多少天,精度是天
CronCalendar
使用表达式排除某些时间段不执行,精度取决于Cron表达式,最大精度到秒
DailyCalendar
指定的时间范围内的每一天不执行,指定每天的时间段,格式是HH:MM[:SS[mmm]],即最大精度可以到毫秒
HolidayCalendar
排除节假日,精度到天
MonthlyCalendar
排除月份中的数天,可选值为1-31,精度是天
WeeklyCalendar
排除星期中的一天或多天,可选值比如为:java.util.Calendar.SUNDAY,精度是天
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| public class CalendarSchedule { public static void main(String[] args) throws SchedulerException { JobDetail jobDetail = JobBuilder.newJob(HelloJob.class) .withIdentity("test") .build(); AnnualCalendar holidays = new AnnualCalendar(); GregorianCalendar nationalDay = new GregorianCalendar(2017, 10, 27); holidays.setDayExcluded(nationalDay,true);
Trigger simpleTrigger = TriggerBuilder.newTrigger() .withIdentity("testTrigger") .withSchedule(SimpleScheduleBuilder.simpleSchedule() .withIntervalInSeconds(1) .repeatForever()) .modifiedByCalendar("holidays") .build(); StdSchedulerFactory stdSchedulerFactory = new StdSchedulerFactory(); Scheduler scheduler = stdSchedulerFactory.getScheduler(); scheduler.addCalendar("holidays",holidays,false,false); scheduler.scheduleJob(jobDetail,simpleTrigger); scheduler.start(); } }
|
定时任务增删改查
参考Scheduler源码中的方法
1 2 3 4 5 6 7 8
| quartz: jobs: - name: myName group: collect cron: 0 0/5 * * * ? * jobClass: com.gamer.me.quartz.jobs.MyJob desc: 我的任务
|
1 2 3 4 5 6 7 8 9
| @Data public class SchedulerJob {
private String name; private String group; private String cron; private String jobClass; private String desc; }
|
1 2 3 4 5 6 7
| @Data @Component @ConfigurationProperties(prefix = "quartz") public class SchedulerJobs {
private List<SchedulerJob> jobs; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
| @Slf4j @Component public class SchedulerManager {
@Autowired private Scheduler scheduler;
public void activeJob(SchedulerJob schedulerJob){ JobKey jobKey = JobKey.jobKey(schedulerJob.getName(), schedulerJob.getGroup()); try { if (scheduler.checkExists(jobKey) && !MonitorCronJob.JOB_NAME.equals(schedulerJob.getName())) { updateJob(schedulerJob); }else { createJob(schedulerJob); } } catch (SchedulerException e) { logger.error("activeJob {}", e); } }
public void createJob(SchedulerJob schedulerJob){ JobKey jobKey = JobKey.jobKey(schedulerJob.getName(), schedulerJob.getGroup()); try { if (scheduler.checkExists(jobKey)) { return; } Class<?> clazz = Class.forName(schedulerJob.getJobClass()); JobDetail jobDetail = getJobDetail(schedulerJob, (Class<Job>) clazz); Trigger cronTrigger = getCronTrigger(schedulerJob); scheduler.scheduleJob(jobDetail, cronTrigger); } catch (ClassNotFoundException | SchedulerException e) { logger.error("createJob {}", e); } }
public void updateJob(SchedulerJob schedulerJob){ TriggerKey triggerKey = TriggerKey.triggerKey(schedulerJob.getName(), schedulerJob.getGroup()); try { Trigger trigger = scheduler.getTrigger(triggerKey); if (trigger == null) { return; } JobKey jobKey = trigger.getJobKey(); String oldCron = ((CronTrigger)trigger).getCronExpression(); if (oldCron.equals(schedulerJob.getCron())){ return; } Trigger cronTrigger = getCronTrigger(schedulerJob); scheduler.rescheduleJob(triggerKey, cronTrigger); } catch (SchedulerException e) { logger.error("updateJob {}", e); } }
public void deleteJobs(List<JobKey> jobKeys) { try { scheduler.deleteJobs(jobKeys); } catch (SchedulerException e) { logger.error("deleteJobs {}", e); } }
private JobDetail getJobDetail(SchedulerJob schedulerJob, Class<Job> clazz) { return JobBuilder.newJob() .ofType(clazz) .withIdentity(schedulerJob.getName(), schedulerJob.getGroup()) .withDescription(schedulerJob.getDesc()) .build(); }
private Trigger getCronTrigger(SchedulerJob schedulerJob) { CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(schedulerJob.getCron()); if (!MonitorCronJob.JOB_NAME.equals(schedulerJob.getName())){ cronScheduleBuilder.withMisfireHandlingInstructionIgnoreMisfires(); } return TriggerBuilder.newTrigger() .withIdentity(schedulerJob.getName(), schedulerJob.getGroup()) .withDescription(schedulerJob.getDesc()) .withSchedule(cronScheduleBuilder) .build(); } }
|
监控其他定时任务的总任务MonitorCronJob(用于监控cron的更新)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| @Slf4j public class MonitorCronJob implements Job {
public static final String JOB_NAME = "monitor_cron"; public static final String GROUP_NAME = "monitor"; public static final String CRON = "0 0/10 * * * ?"; public static final String DESC = "监控cron更新";
@Autowired private SchedulerManager schedulerManager; @Autowired private SchedulerJobs schedulerJobs; @Autowired private ContextRefresher contextRefresher;
@Override public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { contextRefresher.refresh(); Set<JobKey> oldJobKeys = null; try { oldJobKeys = jobExecutionContext.getScheduler().getJobKeys(GroupMatcher.anyJobGroup()); } catch (SchedulerException e) { logger.error("MonitorCronJob {}", e); }
List<String> newJobKeys = new ArrayList<>(); for (SchedulerJob job : schedulerJobs.getJobs()) { if (job.getName().equals(JOB_NAME)) { continue; } newJobKeys.add(job.getName()); logger.info("job【{}】,cron【{}】", job.getName(), job.getCron()); schedulerManager.activeJob(job); } if (oldJobKeys == null) { return; } List<JobKey> shouldDeleteJobKeys = oldJobKeys.stream() .filter(jobKey -> !JOB_NAME.equals(jobKey.getName()) && !newJobKeys.contains(jobKey.getName())) .collect(Collectors.toList()); logger.info("delete jobs {}", shouldDeleteJobKeys); schedulerManager.deleteJobs(shouldDeleteJobKeys); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| @Component public class Initialization implements ApplicationRunner {
@Autowired private SchedulerManager schedulerManager;
@Override public void run(ApplicationArguments args) throws Exception { SchedulerJob schedulerJob = new SchedulerJob(); schedulerJob.setName(MonitorCronJob.JOB_NAME); schedulerJob.setGroup(MonitorCronJob.GROUP_NAME); schedulerJob.setCron(MonitorCronJob.CRON); schedulerJob.setDesc(MonitorCronJob.DESC); schedulerJob.setJobClass(MonitorCronJob.class.getName()); schedulerManager.activeJob(schedulerJob); } }
|