【新睿云 】云服务器0元/年 >>>
JobStore介绍
JobStore是负责跟踪调度器中所有的工作数据:作业任务、触发器、日历等。在配置文件(quartz.properties)中定义JobStore的形式,JobStore有两种RAMJobStore和JDBCJobSTore
- RAMJobStore :配置简单,速度快,但程序停止,数据丢失
- JDBCJobSTore :配置略微复杂,可以保存数据
RAMJobStore
quartz.properties
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
OK了,不需要别的配置,直接启动正常运行就好。
JDBCJobStore
下载sql文件
下载地址:点击下方的Download now
- sql位置:quartz解压根目录/docs/dbTables
- mysql中创建test数据库执行sql文件
配置文件
quartz.properties(这里只给出主要配置,全部配置:参见github源码)
# 持久化配置(存储方式使用JobStoreTX,也就是数据库)
org.quartz.jobStore.class:org.quartz.impl.jdbcjobstore.JobStoreTX
#数据库中quartz表的表名前缀
org.quartz.jobStore.tablePrefix:qrtz_
org.quartz.jobStore.dataSource:myQuartzDB
#是否使用集群(如果项目只部署到 一台服务器,就不用了)
org.quartz.jobStore.isClustered = true
#============================================================================
# Configure Datasources配置数据源(可被覆盖,如果在schedulerFactoryBean指定数据源)
#============================================================================
org.quartz.dataSource.myQuartzDB.driver:com.mysql.jdbc.Driver
org.quartz.dataSource.myQuartzDB.URL:jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8
org.quartz.dataSource.myQuartzDB.user:root
org.quartz.dataSource.myQuartzDB.password:root123
org.quartz.dataSource.myQuartzDB.maxConnections:10
OK了,正常启动运行。
数据库查看
cronTrigger运行的话,数据保存部分表如
下:
QRTZ_CRON_TRIGGERS:
TRIGGER_NAME、
TRIGGER_GROUP、
TRIGGER_EXPRESSION
QRTZ_JOB_DETAIL:
JOB_NAME、
JOB_GROUP、
JOB_CLASS_NAME
QRTZ_TRIGGERS:
TRIGGER_NAME、
TRIGGER_GROUP、
JOB_NAME、
JOB_GROUP、
JOB_CLASS_NAME、
START_TIME、
NEXT_FIRE_TIME、
PREV_FIRE_TIM、
MISFIRE_INSTR
注:从字段可以看出QRTZ_TRIGGERS是一个整合表
springboot-quartz配置JDBCJobStore
pom.xml
org.quartz-scheduler
quartz
org.quartz-scheduler
quartz-jobs
org.springframework
spring-context-support
5.0.7.RELEASE
mysql
mysql-connector-java
org.mybatis.spring.boot
mybatis-spring-boot-starter
1.3.2
com.alibaba
druid-spring-boot-starter
1.1.10
注:
spring-context-support
是spring为了整合quartz及其他框架的中间环境包
applicatin.yml
server:
port: 8080
tomcat:
uri-encoding: utf-8
spring:
datasource:
druid:
# 数据库访问配置, 使用druid数据源
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8
username: root
password: root123
name: anhusky
quartz.properties
#============================================================================
#基础配置
#============================================================================
# 设置调度器的实例名(instanceName) 和实例ID (instanceId)
org.quartz.scheduler.instanceName: MyScheduler
#如果使用集群,instanceId必须唯一,设置成AUTO
org.quartz.scheduler.instanceId = AUTO
#============================================================================
#调度器线程池配置
#============================================================================
org.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool
# 指定多少个工作者线程被创建用来处理 Job
org.quartz.threadPool.threadCount: 20
# 设置工作者线程的优先级(最大值10,最小值1,常用值5)
org.quartz.threadPool.threadPriority: 5
#============================================================================
#Configure JobStore 作业存储配置
#============================================================================
# 持久化配置(存储方式使用JobStoreTX,也就是数据库)
org.quartz.jobStore.class:org.quartz.impl.jdbcjobstore.JobStoreTX
#数据库中quartz表的表名前缀
org.quartz.jobStore.tablePrefix:qrtz_
org.quartz.jobStore.misfireThreshold: 5000
#是否使用集群(如果项目只部署到 一台服务器,就不用了)
org.quartz.jobStore.isClustered = false
SchduleConfig:为ScheduleFactoryBean配置mysql数据源
/**
* 定时任务配置
*
* @author Administrator
*/
@Configuration
public class ScheduleConfig {
@Bean
public SchedulerFactoryBean schedulerFactoryBean(DataSource dataSource) throws IOException {
SchedulerFactoryBean factory = new SchedulerFactoryBean();
factory.setDataSource(dataSource);
// quartz参数
factory.setQuartzProperties(quartzProperties());
factory.setSchedulerName("MyScheduler");
// 延时启动
factory.setStartupDelay(1);
factory.setApplicationContextSchedulerContextKey("applicationContextKey");
// 可选,QuartzScheduler
// 启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了
factory.setOverwriteExistingJobs(true);
// 设置自动启动,默认为true
factory.setAutoStartup(true);
/*
CronTriggerFactoryBean cronTriggerFactoryBean = new CronTriggerFactoryBean();
cronTriggerFactoryBean.setJobDetail(
JobBuilder.newJob(ScheduleJob.class).build());
cronTriggerFactoryBean.setStartDelay(3000);
cronTriggerFactoryBean.setCronExpression("0/10 * * * * ?");
// 通过这个设置 在项目启动时启动
factory.setTriggers(cronTriggerFactoryBean.getObject());
*/
return factory;
}
/**
* 加载Quartz配置
*
* @return
* @throws IOException
*/
@Bean
public Properties quartzProperties() throws IOException {
//使用Spring的PropertiesFactoryBean对属性配置文件进行管理
PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
//注意:quartz的配置文件从指定系统目录中获取,而不是从classpath中获取
propertiesFactoryBean.setLocation(new ClassPathResource("/quartz.properties"));
//propertiesFactoryBean.setLocation(new FileSystemResource(propertiesPath));
//重要:保证其初始化
propertiesFactoryBean.afterPropertiesSet();
return propertiesFactoryBean.getObject();
}
}
JobController
@RequestMapping(value = "/job")
@Controller
public class JobController {
@Autowired
private Scheduler scheduler;
``/**
* 添加定时任务
*/
@PostMapping("/addJob")
@ResponseBody
public Map addJob(@RequestParam(value = "jobClassName") String jobClassName,
@RequestParam(value = "jobGroupName") String jobGroupName,
@RequestParam(value = "cronExpression") String cronExpression) {
Map returnData = new HashMap<>();
try {
JobDetail jobDetail = JobBuilder
.newJob(getClass(jobClassName).getClass())
.withIdentity("测试-1-jojobdetailbdetail")
.build();
//构建CronTrigger触发器
CronTrigger cronTrigger = TriggerBuilder
.newTrigger()
.withSchedule(cronSchedule(cronExpression)
.withMisfireHandlingInstructionDoNothing()
)
.withIdentity("测试-1-cronTrigger")
.build();
//注册调度任务
scheduler.scheduleJob(jobDetail, cronTrigger);
//启动任务
scheduler.start();
returnData.put("msg", "添加调度任务成功");
} catch (Exception e) {
returnData.put("msg", "添加调度任务异常:" + e.getMessage());
}
return returnData;
}
/**
* 暂停定时任务
*
* @param jobClassName
* @param jobGroupName
* @return
*/
@PutMapping(value = "/pauseJob")
@ResponseBody
public Map pauseJob(@RequestParam(value = "jobClassName") String jobClassName,
@RequestParam(value = "jobGroupName") String jobGroupName) {
Map returnData = new HashMap();
try {
//JobKey定义了job的名称和组别
JobKey jobKey = JobKey.jobKey(jobClassName, jobGroupName);
//暂停任务
scheduler.pauseJob(jobKey);
returnData.put("msg", "暂停调度任务成功");
} catch (SchedulerException e) {
returnData.put("msg", "暂停调度任务异常:" + e.getMessage());
} catch (Exception e) {
returnData.put("msg", "暂停调度任务异常:" + e.getMessage());
}
return returnData;
}
/**
* 启动已经暂停的任务
*
* @param jobClassName
* @param jobGroupName
* @return
*/
@PutMapping(value = "/resumeJob")
@ResponseBody
public Map resumeJob(String jobClassName,
String jobGroupName) {
Map returnData = new HashMap();
try {
//JobKey定义了job的名称和组别
JobKey jobKey = JobKey.jobKey(jobClassName, jobGroupName);
//继续任务
scheduler.resumeJob(jobKey);
returnData.put("msg", "继续调度任务成功");
} catch (SchedulerException e) {
returnData.put("msg", "继续调度任务异常:" + e.getMessage());
} catch (Exception e) {
returnData.put("msg", "继续调度任务异常:" + e.getMessage());
}
return returnData;
}
/**
* 更新定时任务:
* --传入的triggerKey有与之匹配的
* --旧触发器的触发时间没有完成
*
* @param jobClassName
* @param jobGroupName
* @param cronExpression
* @return
*/
@PutMapping(value = "/rescheduleJob")
@ResponseBody
public Map rescheduleJob(String jobClassName,
String jobGroupName,
String cronExpression) {
Map returnData = new HashMap();
try {
//构建旧的TriggerKey
TriggerKey triggerKey = TriggerKey.triggerKey(jobClassName, jobGroupName);
//通过cron表达式构建CronScheduleBuilder
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
//从调度容器中获取旧的CronTrigger
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
//更新CronTrigger
trigger = trigger.getTriggerBuilder()
.withIdentity(triggerKey)
//工作项1:job名以及所属组
.withSchedule(scheduleBuilder)
//工作项2:指定调度参数
.build();//构建
//更新调度任务
scheduler.rescheduleJob(triggerKey, trigger);
returnData.put("msg", "更新调度任务成功");
} catch (Exception e) {
returnData.put("msg", "更新调度任务异常:" + e.getMessage());
}
return returnData;
}
/**
* @param jobClassName
* @param jobGroupName
* @return
*/
@DeleteMapping(value = "/removeJob")
@ResponseBody
public Map removeJob(String jobClassName,
String jobGroupName) {
Map returnData = new HashMap();
try {
//获得调度容器
//Scheduler scheduler = getCurrentScheduler();
//TriggerKey定义了trigger的名称和组别
TriggerKey triggerKey = TriggerKey.triggerKey(jobClassName, jobGroupName);
//暂停触发器
scheduler.resumeTrigger(triggerKey);
//暂停触发器
scheduler.unscheduleJob(triggerKey);
//移除任务
scheduler.deleteJob(JobKey.jobKey(jobClassName, jobGroupName));
returnData.put("msg", "删除调度任务成功");
} catch (SchedulerException e) {
returnData.put("msg", "删除调度任务异常:" + e.getMessage());
} catch (Exception e) {
returnData.put("msg", "删除调度任务异常:" + e.getMessage());
}
return returnData;
}
/**
* 获得指定的类实例
*
* @param classname
* @return
* @throws ServerException
*/
private Job getClass(String classname) throws ServerException {
Job baseJob = null;
try {
//加载参数指定的类
Class> classTmp = Class.forName(classname);
//实例化
baseJob = (Job) classTmp.newInstance();
} catch (Exception e) {
System.out.println(classname + "......找不到相应的类");
}
return baseJob;
}
}
源码地址:
github地址