准备写一下quartz的使用流程、注意事项和原理,毕竟用了很久了,不总结就没有提高。
用两天时间创建一个quartz的项目,并根据项目做一下总结,并上传项目源码供大家参考。
quartz的官网地址:http://www.quartz-scheduler.org/
API地址:http://www.quartz-scheduler.org/api/2.2.1/index.html
关于Quartz的介绍 和详解可以看我的上一篇转载的博客,里面介绍的非常详细也非常清楚。https://mp.csdn.net/postedit/85157905
我们这篇就只讲项目,项目上传地址:https://github.com/tiedungao/quartz
项目的代码结构如下:
使用了:Spring Boot+mySql,相应的接口已经实现并通过了单元测试。本来想把前段配置和管理页面也写出来的,发现凭借自己的前端知识去写,画出来的好丑,哈哈,希望前端好的同学能在github上完善完善。
我们下面简单看一下截至当前时间的代码:
主要看service的代码。
package com.spring.quartz.service.impl;
import com.spring.quartz.service.QuartzService;
import com.spring.quartz.utils.SchedulerUtils;
import org.quartz.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import static org.quartz.CronScheduleBuilder.cronSchedule;
import static org.quartz.JobBuilder.newJob;
import static org.quartz.TriggerBuilder.newTrigger;
/**
* @Author: 高铁墩
* @Description:
* @Date: Create in 17:50 2018/12/23
*/
@Service
public class QuartzServiceImpl implements QuartzService {
private static final Logger log = LoggerFactory.getLogger(QuartzServiceImpl.class);
//默认任务组名称
public static final String DEFAULT_JOB_GROUP_NAME = "defaultJobGroup";
//默认触发器组名称
public static final String DEFAULT_TRIGGER_GROUP_NAME = "defaultTriggerGroup";
private static Scheduler scheduler = SchedulerUtils.getScheduler();
public void addJob(String jobName, Class<? extends Job> cls, String cronExpression){
//定义JobDetail
JobDetail jobDetail = newJob(cls).requestRecovery(true)
.withIdentity(jobName,DEFAULT_JOB_GROUP_NAME)
.build();
//定义Trigger
Trigger cronTrigger = newTrigger().withIdentity(jobName+"Trigger",DEFAULT_TRIGGER_GROUP_NAME)
.startNow()
.withSchedule(cronSchedule(cronExpression)
.withMisfireHandlingInstructionFireAndProceed())
.forJob(jobDetail)
.build();
try {
//根据jobDetail和cronTrigger创建任务
scheduler.scheduleJob(jobDetail,cronTrigger);
} catch (SchedulerException e) {
e.printStackTrace();
log.info("执行方法-addJob-时发生异常,异常信息为:"+e.getMessage());
}
}
public void addJobAndData(String jobName,Class<? extends Job> cls,String cronExpression, JobDataMap jobDataMap){
//定义JobDetail
JobDetail jobDetail = newJob(cls).requestRecovery(true)
.usingJobData(jobDataMap)
.withIdentity(jobName,DEFAULT_JOB_GROUP_NAME)
.build();
//定义Trigger
Trigger cronTrigger = newTrigger().withIdentity(jobName+"Trigger",DEFAULT_TRIGGER_GROUP_NAME)
.startNow()
.withSchedule(cronSchedule(cronExpression)
.withMisfireHandlingInstructionFireAndProceed())
.forJob(jobDetail)
.build();
Scheduler scheduler = SchedulerUtils.getScheduler();
try {
scheduler.scheduleJob(jobDetail,cronTrigger);
} catch (SchedulerException e) {
log.info("执行方法-addJobAndData-时发生异常,异常信息为:"+e.getMessage());
e.printStackTrace();
}
}
public void pauseJob(String jobName,String triggerGroupName) throws RuntimeException {
try {
if(null == triggerGroupName)
scheduler.pauseTrigger(new TriggerKey(jobName+"Trigger",DEFAULT_TRIGGER_GROUP_NAME));
else
scheduler.pauseTrigger(new TriggerKey(jobName+"Trigger",triggerGroupName));
} catch (SchedulerException e) {
e.printStackTrace();
log.info("执行方法-pauseJob-时发生异常,异常信息为:"+e.getMessage());
throw new RuntimeException("在调用方法-pauseJob-停止任务"+jobName+"时发生异常,异常信息为:"+e.getMessage());
}
}
public void resumeJob(String jobName,String triggerGroupName){
try {
if(null == triggerGroupName)
scheduler.resumeTrigger(new TriggerKey(jobName+"Trigger",DEFAULT_TRIGGER_GROUP_NAME));
else
scheduler.resumeTrigger(new TriggerKey(jobName+"Trigger",triggerGroupName));
} catch (SchedulerException e) {
e.printStackTrace();
log.info("执行方法-resumeJob-时发生异常,异常信息为:"+e.getMessage());
throw new RuntimeException("在调用方法-resumeJob-恢复任务"+jobName+"时发生异常,异常信息为:"+e.getMessage());
}
}
public void deleteJob(String jobName,String jobGroupName){
try{
if(null == jobGroupName)
scheduler.deleteJob(JobKey.jobKey(jobName,DEFAULT_JOB_GROUP_NAME));
else
scheduler.deleteJob(JobKey.jobKey(jobName,jobGroupName));
} catch (SchedulerException e) {
e.printStackTrace();
log.info("执行方法deleteJob时发生异常,异常信息为:"+e.getMessage());
throw new RuntimeException("在调用方法-deleteJob-删除任务"+jobName+"时发生异常,异常信息为:"+e.getMessage());
}
}
public void startJobs(){
try {
scheduler.start();
} catch (SchedulerException e) {
e.printStackTrace();
log.info("执行方法-startJobs-时发生异常,异常信息为:"+e.getMessage());
throw new RuntimeException("在调用方法-startJobs-启动任务时发生异常,异常信息为:"+e.getMessage());
}
}
public void shutdownJobs(){
try {
scheduler.shutdown();
} catch (SchedulerException e) {
e.printStackTrace();
log.info("执行方法-shutdownJobs-时发生异常,异常信息为:"+e.getMessage());
throw new RuntimeException("在调用方法-shutdownJobs-停止任务时发生异常,异常信息为:"+e.getMessage());
}
}
}
项目里有建表语句,可以根据自己的数据库类型去执行相应的脚本。
代码非常简单,这里不做解释了,工程里有单元测试类,修改一下数据库连接配置就可以运行了,跑一跑就明白大致流程了。
在创建多个Job后,可以验证工程的集群部署,是可以达到负载均衡的,
当然有不明白的地方在下面留言也可以,这个项目很简单,也有很多需要补充的地方,希望有感兴趣的同学一起添砖添瓦。