JobStore是负责跟踪调度器中全部的工做数据:做业任务、触发器、日历等。在配置文件(quartz.properties)中定义JobStore的形式,JobStore有两种RAMJobStore和JDBCJobSTorejava
quartz.propertiesmysql
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
OK了,不须要别的配置,直接启动正常运行就好。git
下载地址:点击下方的Download now github
quartz.properties(这里只给出主要配置,所有配置:参见github源码)spring
# 持久化配置(存储方式使用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了,正常启动运行。sql
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是一个整合表tomcat
pom.xmlspringboot
<!-- quartz --> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> </dependency> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz-jobs</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>5.0.7.RELEASE</version> </dependency> <!-- MySQL驱动 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!-- mybatis --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.2</version> </dependency> <!-- druid数据源驱动 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.10</version> </dependency>
注:
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<String, String> addJob(@RequestParam(value = "jobClassName") String jobClassName, @RequestParam(value = "jobGroupName") String jobGroupName, @RequestParam(value = "cronExpression") String cronExpression) { Map<String, String> 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<String, String> pauseJob(@RequestParam(value = "jobClassName") String jobClassName, @RequestParam(value = "jobGroupName") String jobGroupName) { Map<String, String> returnData = new HashMap<String, String>(); 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<String, String> resumeJob(String jobClassName, String jobGroupName) { Map<String, String> returnData = new HashMap<String, String>(); 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<String, String> rescheduleJob(String jobClassName, String jobGroupName, String cronExpression) { Map<String, String> returnData = new HashMap<String, String>(); 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<String, String> removeJob(String jobClassName, String jobGroupName) { Map<String, String> returnData = new HashMap<String, String>(); 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; } }