SpringBoot自带的定时任务
首先在你的微服务项目中创建一个新的模块,定时调度模块
pom.xml里面关联公共模块common的依赖其他不需要改变
然后启动类别删,启动项目是否报错,写一个简单的测试类访问路径是否成功
package com.jiawa.train.batch.controller;import com.jiawa.train.batch.feign.BusinessFeign;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class TestController {@ResourceBusinessFeign businessFeign;@GetMapping("/hello")public String hello() {return "Hello World! Batch!";}
}
创建一个包job 创建类 SpringBootTestJob.java
package com.jiawa.train.batch.job;import org.springframework.scheduling.annotation.EnableScheduling;import org.springframework.scheduling.annotation.Scheduled;import org.springframework.stereotype.Component;/*** 适合单体应用,不适合集群* 没法实时更改定时任务状态和策略*/@Component@EnableScheduling // 开启定时任务public class SpringBootTestJob {@Scheduled(cron = "0/5 * * * * ?")// 每5秒执行一次 每5秒执行一次 cron 从左到右空格隔开:秒 分钟 小时 日期 月份 星期private void test() {// 增加分布式锁,解决集群问题System.out.println("SpringBootTestJob TEST");}}
多个定时任务就写多个@Scheduled, 定时任务的三要素也要知道:1. 执行的内容:功能逻辑 2. 执行的策略: cron表达式 3. 开关: 开启定时任务
SpringBoot自带的定时任务缺点: 无法实时更改任务状态,就是当我想把定时任务暂停一下今天的数据有问题,但是这个就无法进行暂停所以用专业的任务调度的框架。
SpringBoot自带的定时任务优点: 开发速度快适合小型的项目,两个注解就好了
分布式任务调度框架Quartz集成
首先导入依赖pom.xml。 这里没有版本是因为我的这个是子模块 版本由父模块控制
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-quartz</artifactId></dependency>
跟着思路来导入了依赖之后我们就开始声明我们的任务了, 创建一个配置类 quartzConfig 触发器就是调用前面声明的任务方法来定时
package com.jiawa.train.batch.config;import com.jiawa.train.batch.job.TestJob;import org.quartz.*;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@Configurationpublic class QuartzConfig {/*** 声明一个任务* @return*/@Beanpublic JobDetail jobDetail() {return JobBuilder.newJob(TestJob.class).withIdentity("TestJob", "test")// 任务名称和组构成任务key.storeDurably().build();}/*** 声明一个触发器,什么时候触发这个任务* @return*/@Beanpublic Trigger trigger() {return TriggerBuilder.newTrigger()// 创建一个新的触发器.forJob(jobDetail()) // 将任务detail作为触发器要触发的任务.withIdentity("trigger", "trigger") // 为触发器设置一个唯一标识,例如 "trigger" 和 "trigger".startNow() // 立即触发任务,从当前时间开始.withSchedule(CronScheduleBuilder.cronSchedule("*/2 * * * * ?")) // 设置触发器的调度规则,使用 cron 格式的字符串,表示每隔 2 分钟触发一次任务.build();}}
上面代码写了注释的,任务名称TestJob这里就创建一个任务来对应,实现的是Job是框架quartz里面的接口
@DisallowConcurrentExecution // 禁止并发执行
package com.jiawa.train.batch.job;import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;@DisallowConcurrentExecution // 禁止并发执行
public class TestJob implements Job {@Overridepublic void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {System.out.println("TestJob TEST开始");// try {// Thread.sleep(3000);// } catch (InterruptedException e) {// e.printStackTrace();// }System.out.println("TestJob TEST结束");}
}
这就集成了框架的使用,springboot自带的定时任务也在使用。前面是简单的使用
在项目中集成框架
数据库配置quartz框架调度任务,官方提供的数据库MySQL,创建这几张表记得分库
#
# Quartz seems to work best with the driver mm.mysql-2.0.7-bin.jar
#
# PLEASE consider using mysql with innodb tables to avoid locking issues
#
# In your Quartz properties file, you'll need to set
# org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
#
DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS;
DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE;
DROP TABLE IF EXISTS QRTZ_LOCKS;
DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_JOB_DETAILS;
DROP TABLE IF EXISTS QRTZ_CALENDARS;
CREATE TABLE QRTZ_JOB_DETAILS
(SCHED_NAME VARCHAR(120) NOT NULL comment '定时任务名称',JOB_NAME VARCHAR(200) NOT NULL comment 'job名称',JOB_GROUP VARCHAR(200) NOT NULL comment 'job组',DESCRIPTION VARCHAR(250) NULL comment '描述',JOB_CLASS_NAME VARCHAR(250) NOT NULL comment 'job类名',IS_DURABLE VARCHAR(1) NOT NULL comment '是否持久化',IS_NONCONCURRENT VARCHAR(1) NOT NULL comment '是否非同步',IS_UPDATE_DATA VARCHAR(1) NOT NULL comment '是否更新数据',REQUESTS_RECOVERY VARCHAR(1) NOT NULL comment '请求是否覆盖',JOB_DATA BLOB NULL comment 'job数据',PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
);
CREATE TABLE QRTZ_TRIGGERS
(SCHED_NAME VARCHAR(120) NOT NULL comment '定时任务名称',TRIGGER_NAME VARCHAR(200) NOT NULL comment '触发器名称',TRIGGER_GROUP VARCHAR(200) NOT NULL comment '触发器组',JOB_NAME VARCHAR(200) NOT NULL comment 'job名称',JOB_GROUP VARCHAR(200) NOT NULL comment 'job组',DESCRIPTION VARCHAR(250) NULL comment '描述',NEXT_FIRE_TIME BIGINT(13) NULL comment '下一次触发时间',PREV_FIRE_TIME BIGINT(13) NULL comment '前一次触发时间',PRIORITY INTEGER NULL comment '等级',TRIGGER_STATE VARCHAR(16) NOT NULL comment '触发状态',TRIGGER_TYPE VARCHAR(8) NOT NULL comment '触发类型',START_TIME BIGINT(13) NOT NULL comment '开始时间',END_TIME BIGINT(13) NULL comment '结束时间',CALENDAR_NAME VARCHAR(200) NULL comment '日程名称',MISFIRE_INSTR SMALLINT(2) NULL comment '未触发实例',JOB_DATA BLOB NULL comment 'job数据',PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP)
);
CREATE TABLE QRTZ_SIMPLE_TRIGGERS
(SCHED_NAME VARCHAR(120) NOT NULL comment '定时任务名称',TRIGGER_NAME VARCHAR(200) NOT NULL comment '触发器名称',TRIGGER_GROUP VARCHAR(200) NOT NULL comment '触发器组',REPEAT_COUNT BIGINT(7) NOT NULL comment '重复执行次数',REPEAT_INTERVAL BIGINT(12) NOT NULL comment '重复执行间隔',TIMES_TRIGGERED BIGINT(10) NOT NULL comment '已经触发次数',PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);
CREATE TABLE QRTZ_CRON_TRIGGERS
(SCHED_NAME VARCHAR(120) NOT NULL comment '定时任务名称',TRIGGER_NAME VARCHAR(200) NOT NULL comment '触发器名称',TRIGGER_GROUP VARCHAR(200) NOT NULL comment '触发器组',CRON_EXPRESSION VARCHAR(200) NOT NULL comment 'cron表达式',TIME_ZONE_ID VARCHAR(80) comment '时区',PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);
CREATE TABLE QRTZ_SIMPROP_TRIGGERS
(SCHED_NAME VARCHAR(120) NOT NULL comment '定时任务名称',TRIGGER_NAME VARCHAR(200) NOT NULL comment '触发器名称',TRIGGER_GROUP VARCHAR(200) NOT NULL comment '触发器组',STR_PROP_1 VARCHAR(512) NULL comment '开始配置1',STR_PROP_2 VARCHAR(512) NULL comment '开始配置2',STR_PROP_3 VARCHAR(512) NULL comment '开始配置3',INT_PROP_1 INT NULL comment 'int配置1',INT_PROP_2 INT NULL comment 'int配置2',LONG_PROP_1 BIGINT NULL comment 'long配置1',LONG_PROP_2 BIGINT NULL comment 'long配置2',DEC_PROP_1 NUMERIC(13,4) NULL comment '配置描述1',DEC_PROP_2 NUMERIC(13,4) NULL comment '配置描述2',BOOL_PROP_1 VARCHAR(1) NULL comment 'bool配置1',BOOL_PROP_2 VARCHAR(1) NULL comment 'bool配置2',PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);
CREATE TABLE QRTZ_BLOB_TRIGGERS
(SCHED_NAME VARCHAR(120) NOT NULL comment '定时任务名称',TRIGGER_NAME VARCHAR(200) NOT NULL comment '触发器名称',TRIGGER_GROUP VARCHAR(200) NOT NULL comment '触发器组',BLOB_DATA BLOB NULL comment '数据',PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);
CREATE TABLE QRTZ_CALENDARS
(SCHED_NAME VARCHAR(120) NOT NULL comment '定时任务名称',CALENDAR_NAME VARCHAR(200) NOT NULL comment '日程名称',CALENDAR BLOB NOT NULL comment '日程数据',PRIMARY KEY (SCHED_NAME,CALENDAR_NAME)
);
CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS
(SCHED_NAME VARCHAR(120) NOT NULL comment '定时任务名称',TRIGGER_GROUP VARCHAR(200) NOT NULL comment '触发器组',PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP)
);
CREATE TABLE QRTZ_FIRED_TRIGGERS
(SCHED_NAME VARCHAR(120) NOT NULL comment '定时任务名称',ENTRY_ID VARCHAR(95) NOT NULL comment 'entryId',TRIGGER_NAME VARCHAR(200) NOT NULL comment '触发器名称',TRIGGER_GROUP VARCHAR(200) NOT NULL comment '触发器组',INSTANCE_NAME VARCHAR(200) NOT NULL comment '实例名称',FIRED_TIME BIGINT(13) NOT NULL comment '执行时间',SCHED_TIME BIGINT(13) NOT NULL comment '定时任务时间',PRIORITY INTEGER NOT NULL comment '等级',STATE VARCHAR(16) NOT NULL comment '状态',JOB_NAME VARCHAR(200) NULL comment 'job名称',JOB_GROUP VARCHAR(200) NULL comment 'job组',IS_NONCONCURRENT VARCHAR(1) NULL comment '是否异步',REQUESTS_RECOVERY VARCHAR(1) NULL comment '是否请求覆盖',PRIMARY KEY (SCHED_NAME,ENTRY_ID)
);
CREATE TABLE QRTZ_SCHEDULER_STATE
(SCHED_NAME VARCHAR(120) NOT NULL comment '定时任务名称',INSTANCE_NAME VARCHAR(200) NOT NULL comment '实例名称',LAST_CHECKIN_TIME BIGINT(13) NOT NULL comment '最近检入时间',CHECKIN_INTERVAL BIGINT(13) NOT NULL comment '检入间隔',PRIMARY KEY (SCHED_NAME,INSTANCE_NAME)
);
CREATE TABLE QRTZ_LOCKS
(SCHED_NAME VARCHAR(120) NOT NULL comment '定时任务名称',LOCK_NAME VARCHAR(40) NOT NULL comment 'lock名称',PRIMARY KEY (SCHED_NAME,LOCK_NAME)
);
创建两个固定的配置类,这两个类在任何项目中可以使用都是差不多的固定写法
MyJobFactory.java
package com.jiawa.train.batch.config;import jakarta.annotation.Resource;
import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.scheduling.quartz.SpringBeanJobFactory;
import org.springframework.stereotype.Component;@Component
public class MyJobFactory extends SpringBeanJobFactory {@Resourceprivate AutowireCapableBeanFactory beanFactory;/*** 这里覆盖了super的createJobInstance方法,对其创建出来的类再进行autowire。*/@Overrideprotected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {Object jobInstance = super.createJobInstance(bundle);beanFactory.autowireBean(jobInstance);return jobInstance;}
}
创建一个config工具类,根据数据库进行调度任务 连接数据库指定定时时间。调度器
package com.jiawa.train.batch.config;import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;import javax.sql.DataSource;
import java.io.IOException;@Configuration
public class SchedulerConfig {@Resourceprivate MyJobFactory myJobFactory;@Beanpublic SchedulerFactoryBean schedulerFactoryBean(@Qualifier("dataSource") DataSource dataSource) throws IOException {SchedulerFactoryBean factory = new SchedulerFactoryBean();factory.setDataSource(dataSource);// 连接数据库factory.setJobFactory(myJobFactory);// 指定前面创建的配置类factory.setStartupDelay(2); // 延迟2秒启动return factory;}
}
接下来开始完成定时任务的接口,使得定时任务让接口来控制,首先创建请求数据request
package com.jiawa.train.batch.req;public class CronJobReq {private String group; // 分组private String name;// 任务名称private String description;// 描述private String cronExpression;// 执行时间表达式@Overridepublic String toString() {final StringBuffer sb = new StringBuffer("CronJobDto{");sb.append("cronExpression='").append(cronExpression).append('\'');sb.append(", group='").append(group).append('\'');sb.append(", name='").append(name).append('\'');sb.append(", description='").append(description).append('\'');sb.append('}');return sb.toString();}public String getGroup() {return group;}public void setGroup(String group) {this.group = group;}public String getCronExpression() {return cronExpression;}public void setCronExpression(String cronExpression) {this.cronExpression = cronExpression;}public String getDescription() {return description;}public void setDescription(String description) {this.description = description;}public String getName() {return name;}public void setName(String name) {this.name = name;}
}
设置响应数据类response,进行set和get
package com.jiawa.train.batch.resp;import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonInclude;import java.util.Date;@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class CronJobResp {private String group;// 分组private String name; // 任务名称private String description; // 描述private String state;// 状态private String cronExpression;// 定时任务表达式@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")private Date nextFireTime;// @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")private Date preFireTime;// @Overridepublic String toString() {final StringBuffer sb = new StringBuffer("CronJobDto{");sb.append("cronExpression='").append(cronExpression).append('\'');sb.append(", group='").append(group).append('\'');sb.append(", name='").append(name).append('\'');sb.append(", description='").append(description).append('\'');sb.append(", state='").append(state).append('\'');sb.append(", nextFireTime=").append(nextFireTime);sb.append(", preFireTime=").append(preFireTime);sb.append('}');return sb.toString();}public String getGroup() {return group;}public void setGroup(String group) {this.group = group;}public String getCronExpression() {return cronExpression;}public void setCronExpression(String cronExpression) {this.cronExpression = cronExpression;}public String getDescription() {return description;}public void setDescription(String description) {this.description = description;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Date getNextFireTime() {return nextFireTime;}public void setNextFireTime(Date nextFireTime) {this.nextFireTime = nextFireTime;}public Date getPreFireTime() {return preFireTime;}public void setPreFireTime(Date preFireTime) {this.preFireTime = preFireTime;}public String getState() {return state;}public void setState(String state) {this.state = state;}
}
创建controller类接口,实现对定时任务的控制返回状态 添加定时任务。 当然如果项目中有一个控台端这就是控台的接口
创建定时任务,暂停,重置,启动定时任务,删除以及查看总共有多少个定时任务打开
package com.jiawa.train.batch.controller;import com.jiawa.train.batch.req.CronJobReq;
import com.jiawa.train.batch.resp.CronJobResp;
import com.jiawa.train.common.resp.CommonResp;
import org.quartz.*;
import org.quartz.impl.matchers.GroupMatcher;
import org.quartz.impl.triggers.CronTriggerImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.ArrayList;
import java.util.Date;
import java.util.List;@RestController
@RequestMapping(value = "/admin/job")
public class JobController {private static Logger LOG = LoggerFactory.getLogger(JobController.class);@Autowiredprivate SchedulerFactoryBean schedulerFactoryBean;@RequestMapping(value = "/run")public CommonResp<Object> run(@RequestBody CronJobReq cronJobReq) throws SchedulerException {String jobClassName = cronJobReq.getName();String jobGroupName = cronJobReq.getGroup();LOG.info("手动执行任务开始:{}, {}", jobClassName, jobGroupName);schedulerFactoryBean.getScheduler().triggerJob(JobKey.jobKey(jobClassName, jobGroupName));return new CommonResp<>();}@RequestMapping(value = "/add")public CommonResp add(@RequestBody CronJobReq cronJobReq) {String jobClassName = cronJobReq.getName();String jobGroupName = cronJobReq.getGroup();String cronExpression = cronJobReq.getCronExpression();String description = cronJobReq.getDescription();LOG.info("创建定时任务开始:{},{},{},{}", jobClassName, jobGroupName, cronExpression, description);CommonResp commonResp = new CommonResp();try {// 通过SchedulerFactory获取一个调度器实例Scheduler sched = schedulerFactoryBean.getScheduler();// 启动调度器sched.start();//构建job信息JobDetail jobDetail = JobBuilder.newJob((Class<? extends Job>) Class.forName(jobClassName)).withIdentity(jobClassName, jobGroupName).build();//表达式调度构建器(即任务执行的时间)CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);//按新的cronExpression表达式构建一个新的triggerCronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(jobClassName, jobGroupName).withDescription(description).withSchedule(scheduleBuilder).build();sched.scheduleJob(jobDetail, trigger);} catch (SchedulerException e) {LOG.error("创建定时任务失败:" + e);commonResp.setSuccess(false);commonResp.setMessage("创建定时任务失败:调度异常");} catch (ClassNotFoundException e) {LOG.error("创建定时任务失败:" + e);commonResp.setSuccess(false);commonResp.setMessage("创建定时任务失败:任务类不存在");}LOG.info("创建定时任务结束:{}", commonResp);return commonResp;}@RequestMapping(value = "/pause")public CommonResp pause(@RequestBody CronJobReq cronJobReq) {String jobClassName = cronJobReq.getName();String jobGroupName = cronJobReq.getGroup();LOG.info("暂停定时任务开始:{},{}", jobClassName, jobGroupName);CommonResp commonResp = new CommonResp();try {Scheduler sched = schedulerFactoryBean.getScheduler();sched.pauseJob(JobKey.jobKey(jobClassName, jobGroupName));} catch (SchedulerException e) {LOG.error("暂停定时任务失败:" + e);commonResp.setSuccess(false);commonResp.setMessage("暂停定时任务失败:调度异常");}LOG.info("暂停定时任务结束:{}", commonResp);return commonResp;}@RequestMapping(value = "/resume")public CommonResp resume(@RequestBody CronJobReq cronJobReq) {String jobClassName = cronJobReq.getName();String jobGroupName = cronJobReq.getGroup();LOG.info("重启定时任务开始:{},{}", jobClassName, jobGroupName);CommonResp commonResp = new CommonResp();try {Scheduler sched = schedulerFactoryBean.getScheduler();sched.resumeJob(JobKey.jobKey(jobClassName, jobGroupName));} catch (SchedulerException e) {LOG.error("重启定时任务失败:" + e);commonResp.setSuccess(false);commonResp.setMessage("重启定时任务失败:调度异常");}LOG.info("重启定时任务结束:{}", commonResp);return commonResp;}@RequestMapping(value = "/reschedule")public CommonResp reschedule(@RequestBody CronJobReq cronJobReq) {String jobClassName = cronJobReq.getName();String jobGroupName = cronJobReq.getGroup();String cronExpression = cronJobReq.getCronExpression();String description = cronJobReq.getDescription();LOG.info("更新定时任务开始:{},{},{},{}", jobClassName, jobGroupName, cronExpression, description);CommonResp commonResp = new CommonResp();try {Scheduler scheduler = schedulerFactoryBean.getScheduler();TriggerKey triggerKey = TriggerKey.triggerKey(jobClassName, jobGroupName);// 表达式调度构建器CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);CronTriggerImpl trigger1 = (CronTriggerImpl) scheduler.getTrigger(triggerKey);trigger1.setStartTime(new Date()); // 重新设置开始时间CronTrigger trigger = trigger1;// 按新的cronExpression表达式重新构建triggertrigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withDescription(description).withSchedule(scheduleBuilder).build();// 按新的trigger重新设置job执行scheduler.rescheduleJob(triggerKey, trigger);} catch (Exception e) {LOG.error("更新定时任务失败:" + e);commonResp.setSuccess(false);commonResp.setMessage("更新定时任务失败:调度异常");}LOG.info("更新定时任务结束:{}", commonResp);return commonResp;}@RequestMapping(value = "/delete")public CommonResp delete(@RequestBody CronJobReq cronJobReq) {String jobClassName = cronJobReq.getName();String jobGroupName = cronJobReq.getGroup();LOG.info("删除定时任务开始:{},{}", jobClassName, jobGroupName);CommonResp commonResp = new CommonResp();try {Scheduler scheduler = schedulerFactoryBean.getScheduler();scheduler.pauseTrigger(TriggerKey.triggerKey(jobClassName, jobGroupName));scheduler.unscheduleJob(TriggerKey.triggerKey(jobClassName, jobGroupName));scheduler.deleteJob(JobKey.jobKey(jobClassName, jobGroupName));} catch (SchedulerException e) {LOG.error("删除定时任务失败:" + e);commonResp.setSuccess(false);commonResp.setMessage("删除定时任务失败:调度异常");}LOG.info("删除定时任务结束:{}", commonResp);return commonResp;}@RequestMapping(value="/query")public CommonResp query() {LOG.info("查看所有定时任务开始");CommonResp commonResp = new CommonResp();List<CronJobResp> cronJobDtoList = new ArrayList();try {Scheduler scheduler = schedulerFactoryBean.getScheduler();for (String groupName : scheduler.getJobGroupNames()) {for (JobKey jobKey : scheduler.getJobKeys(GroupMatcher.jobGroupEquals(groupName))) {CronJobResp cronJobResp = new CronJobResp();cronJobResp.setName(jobKey.getName());cronJobResp.setGroup(jobKey.getGroup());//get job's triggerList<Trigger> triggers = (List<Trigger>) scheduler.getTriggersOfJob(jobKey);CronTrigger cronTrigger = (CronTrigger) triggers.get(0);cronJobResp.setNextFireTime(cronTrigger.getNextFireTime());cronJobResp.setPreFireTime(cronTrigger.getPreviousFireTime());cronJobResp.setCronExpression(cronTrigger.getCronExpression());cronJobResp.setDescription(cronTrigger.getDescription());Trigger.TriggerState triggerState = scheduler.getTriggerState(cronTrigger.getKey());cronJobResp.setState(triggerState.name());cronJobDtoList.add(cronJobResp);}}} catch (SchedulerException e) {LOG.error("查看定时任务失败:" + e);commonResp.setSuccess(false);commonResp.setMessage("查看定时任务失败:调度异常");}commonResp.setContent(cronJobDtoList);LOG.info("查看定时任务结束:{}", commonResp);return commonResp;}}
开始测试接口是否成功
POST http://localhost:8000/batch/admin/job/add
Content-Type: application/json{"name": "com.jiawa.train.batch.job.TestJob","jobGroupName": "default","cronExpression": "*/2 * * * * ?","desc": "test job"
}###GET http://localhost:8000/batch/admin/job/query###POST http://localhost:8000/batch/admin/job/pause
Content-Type: application/json{"name": "com.jiawa.train.batch.job.TestJob","jobGroupName": "default"
}###POST http://localhost:8000/batch/admin/job/resume
Content-Type: application/json{"name": "com.jiawa.train.batch.job.TestJob","jobGroupName": "default"
}###POST http://localhost:8000/batch/admin/job/reschedule
Content-Type: application/json{
"name": "com.jiawa.train.batch.job.TestJob",
"jobGroupName": "default",
"cronExpression": "*/5 * * * * ?",
"desc": "test job"
}###POST http://localhost:8000/batch/admin/job/delete
Content-Type: application/json{
"name": "com.jiawa.train.batch.job.TestJob",
"jobGroupName": "default"
}###POST http://localhost:8000/batch/admin/job/run
Content-Type: application/json{
"name": "com.jiawa.train.batch.job.DailyTrainJob",
"jobGroupName": "default"
}
以上就是接口控制定时任务的开始结束添加删除的功能。
下一篇就是多节点场景中如何调度任务quartz