项目中使用quartz定时任务框架记录

Posted 你若安好便是晴天

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了项目中使用quartz定时任务框架记录相关的知识,希望对你有一定的参考价值。

1.简述

项目中需求是在开始时间和结束时间周期性的执行指定的任务(脚本),结束后能够更新任务状态,对应的任务比较耗时,每个任务可能执行的时间是10s到几分钟。依据需求进行设计,周期性的任务有定时任务框架quartz完成,定时任务每次执行将任务信息扔到消息队列中,消息队列消费者多线程消费消息,任务执行完成后确认消费了消息,并更新任务结果状态

2.quartz 调度器

A.注册Scheduler

配置文件
```java
org.quartz.scheduler.instanceName = PeriodCheckQuartzScheduler
org.quartz.scheduler.rmi.export = false
org.quartz.scheduler.rmi.proxy = false
org.quartz.scheduler.wrapJobExecutionInUserTransaction = false
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 5
org.quartz.threadPool.threadPriority = 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true
org.quartz.jobStore.misfireThreshold = 5000
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.jobStore.dataSource = qzDS
org.quartz.dataSource.qzDS.driver = com.mysql.jdbc.Driver
org.quartz.dataSource.qzDS.URL = jdbc:mysql://10.50.0.152:3306/cmp?characterEncoding=utf8
org.quartz.dataSource.qzDS.user = root
org.quartz.dataSource.qzDS.password = 123456
```
B.注册bean

 ```java
 @Configuration
public class SchedulerConfig {
    @Autowired
 private SpringJobFactory springJobFactory;
    @Autowired
 private QuarzProperties quarzProperties;
    @Bean(name = "SchedulerFactory")
    public SchedulerFactoryBean schedulerFactoryBean() throws IOException {
        SchedulerFactoryBean factory = new SchedulerFactoryBean();
        factory.setAutoStartup(true);
        factory.setStartupDelay(5);//延时5秒启动
 factory.setQuartzProperties(quartzProperties());
        factory.setJobFactory(springJobFactory);
        return factory;
    }
    @Bean
 public Properties quartzProperties() throws IOException {
        PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
        propertiesFactoryBean.setProperties(quarzProperties.getQuartzProperties());
        propertiesFactoryBean.afterPropertiesSet();
        return propertiesFactoryBean.getObject();
    }
    @Bean(name="Scheduler")
    public Scheduler scheduler() throws IOException {
        return schedulerFactoryBean().getScheduler();
    }
}
 ```

3.自定义Job任务

    import org.quartz.DisallowConcurrentExecution;
    import org.quartz.Job;
    import org.quartz.JobExecutionContext;
    import org.quartz.JobExecutionException;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import java.io.Serializable;
    
    @DisallowConcurrentExecution
    public class PeriodCheckJob implements Job, Serializable {
        private static final long serialVersionUID = 1L;
        private static final Logger logger = LoggerFactory.getLogger(PeriodCheckJob.class);
        @Autowired
        private PeriodCheckService periodCheckService;
        @Override
        public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
            //业务逻辑
        }
    }

4.JobDetail和Trigger

Class dj = Class.forName(PeriodCheckJob.class.getName());
dj.newInstance();
JobDetail jobDetail = JobBuilder.newJob(dj).withIdentity(new JobKey(PeriodCheckJob.class.toString() + expression + checkId, JOB_GROUP)).withDescription("description").build();
jobDetail.getJobDataMap().put("checkId", checkId);
CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(expression).withMisfireHandlingInstructionDoNothing();
//开始时间和结束时间,以及通过cron表达式定义执行时间
Trigger trigger = trigger = TriggerBuilder.newTrigger().withIdentity(new TriggerKey(PeriodCheck.class.toString() + expression + checkId, "TRIGGER_KEY_" + expression))
            .startAt(startTime).endAt(endTime).withSchedule(cronScheduleBuilder).build();
scheduler.scheduleJob(jobDetail, trigger);

5.任务状态

A.关闭任务
JobKey jobKey = new JobKey(PeriodCheckJob.class.toString() + expression + checkId, JOB_GROUP); 
scheduler.pauseJob(jobKey);//暂停任务
scheduler.deleteJob(jobKey);//关闭任务
scheduler.resumeJob(jobKey);//重启任务
//修改任务任务配置信息
TriggerKey triggerKey = new TriggerKey(InspectPlan.class.toString(), planId.toString());
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(inspectPlan.getCronExpression());
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
scheduler.rescheduleJob(triggerKey, trigger);//重新调度任务

###6.任务结束事件监听

    @Component("periodCheckJobListener")
    @Slf4j
    public class PeriodCheckJobListener implements ChannelAwareMessageListener {
 
public void onMessage(Message message, Channel channel) {
       //通过message获取任务信息,更改业务状态
   }
    }

7.项目业务有需要知道所有定时任务最近一次的执行时间

实现方式1:可以在实现JobDetail中获取上下文环境,得到每一个任务的下一次
执行时间
实现方式2: 直接查询quartz trigger表中trigger_state状态为waiting的next_fire_time,然后转换成Date类型。

select NEXT_FIRE_TIME from QRTZ_TRIGGERS where trigger_state = \'WAITING\' order by next_fire_time desc limit 1

8.预估定时任务在某一段时间内的执行时间点

CronTriggerImpl triggerImpl = new CronTriggerImpl();
triggerImpl.setCronExpression(expression);
List<Date> dates = TriggerUtils.computeFireTimesBetween(triggerImpl, null, startDate, endDate);

expression: cron表达式
startDate:开始时间
endDate: 结束时间

以上是关于项目中使用quartz定时任务框架记录的主要内容,如果未能解决你的问题,请参考以下文章

分布式定时任务调度框架Quartz学习与实战记录完整篇

分布式定时任务调度框架Quartz学习与实战记录完整篇

分布式定时任务调度框架Quartz学习与实战记录完整篇

分布式定时任务调度框架 - Quartz学习及实战记录笔记

分布式定时任务调度框架 - Quartz学习及实战记录笔记

Quartz-定时任务框架