quartz 定时任务调度管理器
本项目使用的是spring-quartz
以下配置可以开启多个已知定时任务
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:task="http://www.springframework.org/schema/task" 5 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 6 http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd"> 7 8 9 <!--<util:properties id="quartz" location="classpath:quartz.properties" />--> 10 11 <!-- single thread --> 12 <task:executor id="threadPoolTaskExecutor" pool-size="1"/> 13 14 <!-- Scheduler factory bean to glue together jobDetails and triggers to Configure Quartz Scheduler --> 15 <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> 16 <property name="jobFactory"> 17 <bean class="com.xxx.servicenode.pushtaskserver.quartz.task.MySpringBeanJobFactory"/> 18 </property> 19 <property name="startupDelay" value="0"/> 20 <property name="taskExecutor" ref="threadPoolTaskExecutor"/> 21 <property name="triggers"> 22 <list> 23 <ref bean="cronTrigger"/> 24 </list> 25 </property> 26 </bean> 27 28 <!-- Run the job every 5 seconds --> 29 <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> 30 <property name="jobDetail" ref="myjobDetail"/> 31 <!--<property name="cronExpression" value="0/5 * * ? * SAT-SUN" />--> 32 <property name="cronExpression" value="#{config['quartz.time']}"/> 33 </bean> 34 <bean id="myjobDetail" class="org.springframework.scheduling.quartz.JobDetailFactoryBean"> 35 <property name="jobClass" value="com.xxx.servicenode.pushtaskserver.quartz.task.MyJob"/> 36 </bean> 37 38 </beans>
MySpringBeanJobFactory:
1 public class MySpringBeanJobFactory extends SpringBeanJobFactory { 2 3 @Autowired 4 private AutowireCapableBeanFactory autowireCapableBeanFactory; 5 6 @Override 7 protected Object createJobInstance(TriggerFiredBundle bundle)throws Exception { 8 Object jobInstance = super.createJobInstance(bundle); 9 autowireCapableBeanFactory.autowireBean(jobInstance); 10 return jobInstance; 11 } 12 }
MyJob:
1 public class MyJob extends QuartzJobBean { 2 3 private final static Logger logger = LoggerFactory.getLogger(MyJob.class); 4 5 @Override 6 protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException { 7 //处理自己的业务逻辑 8 } 9 }
定时任务调度:
适用场景:多个未知定时任务
1 public class QuartzManager { 2 3 private final static Logger logger = LoggerFactory.getLogger(QuartzManager.class); 4 5 private static SchedulerFactory gSchedulerFactory = new StdSchedulerFactory(); 6 private static String JOB_GROUP_NAME = "MY_JOBGROUP_NAME"; 7 private static String TRIGGER_GROUP_NAME = "MY_TRIGGERGROUP_NAME"; 8 private static Scheduler scheduler; 9 10 /** 11 * 创建一个地上那个会任务并启动 12 * 13 * @param jobName 14 * @param cls 15 * @param cron 16 * @param messageId 17 */ 18 public static void addJob(String jobName, Class cls, String cron, int messageId, int timingExpId) { 19 try { 20 Scheduler sched = gSchedulerFactory.getScheduler(); 21 JobDetail job = JobBuilder.newJob(cls).withIdentity(jobName, JOB_GROUP_NAME).build(); 22 JobDataMap jobDataMap = job.getJobDataMap(); 23 jobDataMap.put("messageId", messageId); 24 jobDataMap.put("timingExpId", timingExpId); 25 // 表达式调度构建器 26 CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cron); 27 // 按新的cronExpression表达式构建一个新的trigger 28 Trigger trigger = TriggerBuilder.newTrigger().withIdentity(jobName, TRIGGER_GROUP_NAME) 29 .withSchedule(scheduleBuilder).build(); 30 // 交给scheduler去调度 31 sched.scheduleJob(job, trigger); 32 // 启动 33 if (!sched.isShutdown()) { 34 sched.start(); 35 logger.info("新任务创建完毕,并启动 !jobName:[" + jobName + "]"); 36 } 37 } catch (Exception e) { 38 String message = e.getMessage(); 39 if (message.contains("will never fire")) { 40 logger.info("当前任务不会被触发,设置为失效状态,timingExpId:[" + timingExpId + "] ..."); 41 PushTaskServerService pushTaskServerService = SpringContextHolder.getInstance().getBean(PushTaskServerService.class); 42 pushTaskServerService.setTimingStatus(timingExpId); 43 } 44 Throwable cause = e.getCause(); 45 46 logger.error("新任务创建、并启动 失败", e); 47 } 48 } 49 50 /** 51 * 移除一个定时任务 52 * 53 * @param jobName 54 */ 55 public static void removeJob(String jobName) { 56 TriggerKey triggerKey = TriggerKey.triggerKey(jobName, TRIGGER_GROUP_NAME); 57 JobKey jobKey = JobKey.jobKey(jobName, JOB_GROUP_NAME); 58 try { 59 Scheduler sched = gSchedulerFactory.getScheduler(); 60 Trigger trigger = (Trigger) sched.getTrigger(triggerKey); 61 if (trigger == null) { 62 return; 63 } 64 // 停止触发器 65 sched.pauseTrigger(triggerKey); 66 // 移除触发器 67 sched.unscheduleJob(triggerKey); 68 // 删除任务 69 sched.deleteJob(jobKey); 70 logger.info("移除任务,完毕!jobName:[" + jobName + "]"); 71 } catch (Exception e) { 72 throw new RuntimeException(e); 73 } 74 } 75 76 /** 77 * 查到当前任务的状态 78 * 79 * @param jobName 80 * @return NONE 无, 81 * NORMAL, 正常 82 * PAUSED, 暂停 83 * COMPLETE, 完成 84 * ERROR, 错误, 85 * BLOCKED 受阻; 86 */ 87 public static String getTriggerState(String jobName) { 88 TriggerKey triggerKey = TriggerKey.triggerKey(jobName, TRIGGER_GROUP_NAME); 89 String name = null; 90 try { 91 Scheduler sched = gSchedulerFactory.getScheduler(); 92 Trigger.TriggerState triggerState = sched.getTriggerState(triggerKey); 93 name = triggerState.name(); 94 } catch (Exception e) { 95 logger.error("获取任务状态失败!jobName:[" + jobName + "]", e); 96 } 97 return name; 98 } 99 100 /** 101 * 暂停一个任务 102 * 103 * @param jobName 104 */ 105 public static void pauseJob(String jobName) { 106 JobKey jobKey = JobKey.jobKey(jobName, JOB_GROUP_NAME); 107 try { 108 Scheduler sched = gSchedulerFactory.getScheduler(); 109 sched.pauseJob(jobKey); 110 } catch (Exception e) { 111 logger.error("暂停任务失败!jobName:[" + jobName + "]", e); 112 } 113 } 114 115 /** 116 * 恢复一个任务 117 * 118 * @param jobName 119 */ 120 public static void resumeJob(String jobName) { 121 JobKey jobKey = JobKey.jobKey(jobName, JOB_GROUP_NAME); 122 try { 123 Scheduler sched = gSchedulerFactory.getScheduler(); 124 sched.resumeJob(jobKey); 125 } catch (SchedulerException e) { 126 logger.error("恢复任务失败!jobName:[" + jobName + "]", e); 127 128 } 129 } 130 131 /** 132 * 获取定时任务调度中全部任务 133 */ 134 public static void getAllJobs() { 135 try { 136 Scheduler sched = gSchedulerFactory.getScheduler(); 137 List<String> triggerGroupNames = sched.getTriggerGroupNames(); 138 logger.info("定时任务管理器中全部任务 . triggerGroupNames.size:[" + triggerGroupNames.size() + "] ... "); 139 for (String group : triggerGroupNames) { 140 logger.info("定时任务管理器 TriggerGroupName:[" + group + "] ... "); 141 Set<TriggerKey> triggerKeys = sched.getTriggerKeys(GroupMatcher.triggerGroupEquals(group)); 142 logger.info("定时任务管理器[" + group + "]分组下任务size:[" + triggerKeys.size() + "] ... "); 143 for (TriggerKey triggerKey : triggerKeys) { 144 String jobName = triggerKey.getName(); 145 logger.info("定时任务管理器[" + group + "]分组下任务Name:[" + jobName + "] ... "); 146 String triggerState = getTriggerState(jobName); 147 logger.info("定时任务管理器[" + group + "]分组下任务Name:[" + jobName + "],任务状态:[" + triggerState + "] ... "); 148 } 149 } 150 } catch (Exception e) { 151 logger.info("获取任务调度管理器中全部任务失败", e); 152 } 153 } 154 155 /** 156 * 开启全部任务 157 */ 158 public static void startJobs() { 159 try { 160 scheduler.start(); 161 } catch (Exception e) { 162 throw new RuntimeException(e); 163 } 164 } 165 166 /** 167 * 关闭全部任务 168 */ 169 public void shutdownJobs() { 170 try { 171 if (!scheduler.isShutdown()) { 172 scheduler.shutdown(); 173 } 174 } catch (Exception e) { 175 logger.error("关闭全部任务失败", e); 176 } 177 } 178 179 /** 180 * 删除定时任务 181 * 182 * @param jobName 183 * @param jobGroupName 184 * @param triggerName 185 * @param triggerGroupName 186 */ 187 public void removeJob(String jobName, String jobGroupName, String triggerName, String triggerGroupName) { 188 try { 189 TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName); 190 // 停止触发器 191 scheduler.pauseTrigger(triggerKey); 192 // 移除触发器 193 scheduler.unscheduleJob(triggerKey); 194 // 删除任务 195 scheduler.deleteJob(JobKey.jobKey(jobName, jobGroupName)); 196 } catch (Exception e) { 197 throw new RuntimeException(e); 198 } 199 } 200 201 public void startJob(String jobName, String jobGroupName, String triggerName, String triggerGroupName) { 202 try { 203 TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName); 204 Trigger.TriggerState triggerState = scheduler.getTriggerState(triggerKey); 205 } catch (Exception e) { 206 throw new RuntimeException(e); 207 } 208 } 209 /** 210 * 创建启动定时任务 211 * 212 * @param jobClass 213 */ 214 public void createTrgger(Class jobClass) { 215 try { 216 //定时任务名称 217 String jobName = ""; 218 String triggerName = ""; 219 String triggerGroupName = ""; 220 String jobGroupName = ""; 221 String cron = ""; 222 JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName).build(); 223 jobDetail.getJobDataMap().put("messageId", "1"); 224 TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger(); 225 // 触发器名,触发器组 226 triggerBuilder.withIdentity(triggerName, triggerGroupName); 227 triggerBuilder.startNow(); 228 // 触发器时间设定 229 triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron)); 230 // 创建Trigger对象 231 CronTrigger trigger = (CronTrigger) triggerBuilder.build(); 232 // 调度容器设置JobDetail和Trigger 233 scheduler.scheduleJob(jobDetail, trigger); 234 // 启动 235 if (!scheduler.isShutdown()) { 236 scheduler.start(); 237 } 238 } catch (Exception e) { 239 logger.error("", e); 240 } 241 } 242 243 public Scheduler getScheduler() { 244 return scheduler; 245 } 246 247 public void setScheduler(Scheduler scheduler) { 248 this.scheduler = scheduler; 249 } 250 }
经测试:定时任务调度器开启的定时任务,当任务状态为:完成(COMPLETE)时,此任务自动回收
pom.xml(本人是pom版本)
1 <dependency> 2 <groupId>org.quartz-scheduler</groupId> 3 <artifactId>quartz</artifactId> 4 <version>2.2.3</version> 5 <exclusions> 6 <exclusion> 7 <groupId>org.slf4j</groupId> 8 <artifactId>slf4j-api</artifactId> 9 </exclusion> 10 </exclusions> 11 </dependency> 12 <!-- https://mvnrepository.com/artifact/org.quartz-scheduler/quartz-jobs --> 13 <dependency> 14 <groupId>org.quartz-scheduler</groupId> 15 <artifactId>quartz-jobs</artifactId> 16 <version>2.2.3</version> 17 </dependency>
参考文档:http://www.quartz-scheduler.org/documentation/quartz-2.3.0/cookbook/