SpringBoot定时任务 - 基础quartz实现方式 准备知识点 什么是QuartzQuartz的体系结构什么是Quartz持久化 实现案例 - 单实例方式实现案例 - 分布式方式 后端实现前端实现测试效果 示例源码参考文章最为常用定时任务框架是Quartz;并且Spring也集成了Quartz的框架;Quartz不仅支持单实例方式还支持分布式方式。本文主要介绍Quartz;基础的Quartz的集成案例本;以及实现基于数据库的分布式任务管理和控制job生命周期。;pdai
需要了解常用的Quartz框架。
来源百度百科, 官网地址;www.quartz-scheduler.org/
Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目;它可以与J2EE与J2SE应用程序相结合也可以单独使用。Quartz可以用来创建简单或为运行十个;百个;甚至是好几万个Jobs这样复杂的程序。Jobs可以做成标准的Java组件或 EJBs。
它的特点如下
纯java实现;可以作为独立的应用程序;也可以嵌入在另一个独立式应用程序运行强大的调度功能;Spring默认的调度框架;灵活可配置;作业持久化;调度环境持久化机制;可以保存并恢复调度现场。系统关闭数据不会丢失;灵活的应用方式;可以任意定义触发器的调度时间表;支持任务和调度各种组合;组件式监听器、各种插件、线程池等功能;多种存储方式等;分布式和集群能力;可以被实例化;一个Quartz集群中的每个节点作为一个独立的Quartz使用;通过相同的数据库表来感知到另一个Quartz应用注; 上图来源于www.cnblogs.com/jijm123/p/1…
当程序突然被中断时;如断电;内存超出时;很有可能造成任务的丢失。 可以将调度信息存储到数据库里面;进行持久化;当程序被中断后;再次启动;仍然会保留中断之前的数据;继续执行;而并不是重新开始。
Quartz提供了两种持久化方式Quartz提供两种基本作业存储类型:
RAMJobStore在默认情况下Quartz将任务调度的运行信息保存在内存中;这种方法提供了最佳的性能;因为内存中数据访问最快。不足之处是缺乏数据的持久性;当程序路途停止或系统崩溃时;所有运行的信息都会丢失。
JobStoreTX所有的任务信息都会保存到数据库中;可以控制事物;还有就是如果应用服务器关闭或者重启;任务信息都不会丢失;并且可以恢复因服务器关闭或者重启而导致执行失败的任务。
引入POM依赖本例将展示quartz实现单实例方式。
<dependency>
<groupId>org.springFramework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
复制代码
定义Job
只需要继承QuartzJobBean;并重载executeInternal方法即可定义你自己的Job执行逻辑。
;Slf4j
public class HelloJob extends QuartzJobBean {
;Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
// get parameters
context.getJobDetail().getJobDataMap().forEach(
(k, v) -> log.info(;param, key:{}, value:{};, k, v)
);
// your logics
log.info(;Hello Job执行时间: ; ; new Date());
}
}
复制代码
配置Job
JobDetail, Trigger, Schedule(这里采用CronScheduleBuilder)
/**
* ;author pdai
*/
;Configuration
public class QuartzConfig {
;Bean(;helloJob;)
public JobDetail helloJobDetail() {
return JobBuilder.newJob(HelloJob.class)
.withIdentity(;DateTimeJob;)
.usingJobData(;msg;, ;Hello Quartz;)
.storeDurably()//即使没有Trigger关联时;也不需要删除该JobDetail
.build();
}
;Bean
public Trigger printTimeJobTrigger() {
// 每秒执行一次
CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(;0/1 * * * * ?;);
return TriggerBuilder.newTrigger()
.forJob(helloJobDetail())
.withIdentity(;quartzTaskService;)
.withSchedule(cronScheduleBuilder)
.build();
}
}
复制代码
执行测试
2021-10-01 13:09:00.380 INFO 38484 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2021-10-01 13:09:00.391 INFO 38484 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2021-10-01 13:09:00.392 INFO 38484 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.50]
2021-10-01 13:09:00.526 INFO 38484 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2021-10-01 13:09:00.526 INFO 38484 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1424 ms
2021-10-01 13:09:00.866 INFO 38484 --- [ main] org.quartz.impl.StdSchedulerFactory : Using default implementation for ThreadExecutor
2021-10-01 13:09:00.877 INFO 38484 --- [ main] org.quartz.core.SchedulerSignalerImpl : Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl
2021-10-01 13:09:00.877 INFO 38484 --- [ main] org.quartz.core.QuartzScheduler : Quartz Scheduler v.2.3.2 created.
2021-10-01 13:09:00.878 INFO 38484 --- [ main] org.quartz.simpl.RAMJobStore : RAMJobStore initialized.
2021-10-01 13:09:00.878 INFO 38484 --- [ main] org.quartz.core.QuartzScheduler : Scheduler meta-data: Quartz Scheduler (v2.3.2) ;quartzScheduler; with instanceId ;NON_CLUSTERED;
Scheduler class: ;org.quartz.core.QuartzScheduler; - running locally.
NOT STARTED.
Currently in standby mode.
Number of jobs executed: 0
Using thread pool ;org.quartz.simpl.SimpleThreadPool; - with 10 threads.
Using job-store ;org.quartz.simpl.RAMJobStore; - which does not support persistence. and is not clustered.
2021-10-01 13:09:00.878 INFO 38484 --- [ main] org.quartz.impl.StdSchedulerFactory : Quartz scheduler ;quartzScheduler; initialized from an externally provided properties instance.
2021-10-01 13:09:00.879 INFO 38484 --- [ main] org.quartz.impl.StdSchedulerFactory : Quartz scheduler version: 2.3.2
2021-10-01 13:09:00.879 INFO 38484 --- [ main] org.quartz.core.QuartzScheduler : JobFactory set to: org.springframework.scheduling.quartz.SpringBeanJobFactory;6075b2d3
2021-10-01 13:09:00.922 INFO 38484 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ;;
2021-10-01 13:09:00.923 INFO 38484 --- [ main] o.s.s.quartz.SchedulerFactoryBean : Starting Quartz Scheduler now
2021-10-01 13:09:00.923 INFO 38484 --- [ main] org.quartz.core.QuartzScheduler : Scheduler quartzScheduler_$_NON_CLUSTERED started.
2021-10-01 13:09:00.933 INFO 38484 --- [ main] tech.pdai.springboot.quartz.App : Started App in 2.64 seconds (JVM running for 3.621)
2021-10-01 13:09:00.931 INFO 38484 --- [eduler_Worker-1] t.pdai.springboot.quartz.job.HelloJob : param, key:msg, value:Hello Quartz
2021-10-01 13:09:00.933 INFO 38484 --- [eduler_Worker-1] t.pdai.springboot.quartz.job.HelloJob : Hello Job执行时间: Wed Oct 27 13:09:00 CST 2021
2021-10-01 13:09:01.001 INFO 38484 --- [eduler_Worker-2] t.pdai.springboot.quartz.job.HelloJob : param, key:msg, value:Hello Quartz
2021-10-01 13:09:01.001 INFO 38484 --- [eduler_Worker-2] t.pdai.springboot.quartz.job.HelloJob : Hello Job执行时间: Wed Oct 27 13:09:01 CST 2021
2021-10-01 13:09:02.000 INFO 38484 --- [eduler_Worker-3] t.pdai.springboot.quartz.job.HelloJob : param, key:msg, value:Hello Quartz
2021-10-01 13:09:02.000 INFO 38484 --- [eduler_Worker-3] t.pdai.springboot.quartz.job.HelloJob : Hello Job执行时间: Wed Oct 27 13:09:02 CST 2021
2021-10-01 13:09:03.000 INFO 38484 --- [eduler_Worker-4] t.pdai.springboot.quartz.job.HelloJob : param, key:msg, value:Hello Quartz
2021-10-01 13:09:03.001 INFO 38484 --- [eduler_Worker-4] t.pdai.springboot.quartz.job.HelloJob : Hello Job执行时间: Wed Oct 27 13:09:03 CST 2021
2021-10-01 13:09:04.001 INFO 38484 --- [eduler_Worker-5] t.pdai.springboot.quartz.job.HelloJob : param, key:msg, value:Hello Quartz
2021-10-01 13:09:04.001 INFO 38484 --- [eduler_Worker-5] t.pdai.springboot.quartz.job.HelloJob : Hello Job执行时间: Wed Oct 27 13:09:04 CST 2021
2021-10-01 13:09:05.002 INFO 38484 --- [eduler_Worker-6] t.pdai.springboot.quartz.job.HelloJob : param, key:msg, value:Hello Quartz
2021-10-01 13:09:05.003 INFO 38484 --- [eduler_Worker-6] t.pdai.springboot.quartz.job.HelloJob : Hello Job执行时间: Wed Oct 27 13:09:05 CST 2021
2021-10-01 13:09:06.000 INFO 38484 --- [eduler_Worker-7] t.pdai.springboot.quartz.job.HelloJob : param, key:msg, value:Hello Quartz
2021-10-01 13:09:06.001 INFO 38484 --- [eduler_Worker-7] t.pdai.springboot.quartz.job.HelloJob : Hello Job执行时间: Wed Oct 27 13:09:06 CST 2021
2021-10-01 13:09:07.002 INFO 38484 --- [eduler_Worker-8] t.pdai.springboot.quartz.job.HelloJob : param, key:msg, value:Hello Quartz
2021-10-01 13:09:07.002 INFO 38484 --- [eduler_Worker-8] t.pdai.springboot.quartz.job.HelloJob : Hello Job执行时间: Wed Oct 27 13:09:07 CST 2021
2021-10-01 13:09:08.002 INFO 38484 --- [eduler_Worker-9] t.pdai.springboot.quartz.job.HelloJob : param, key:msg, value:Hello Quartz
2021-10-01 13:09:08.003 INFO 38484 --- [eduler_Worker-9] t.pdai.springboot.quartz.job.HelloJob : Hello Job执行时间: Wed Oct 27 13:09:08 CST 2021
2021-10-01 13:09:09.000 INFO 38484 --- [duler_Worker-10] t.pdai.springboot.quartz.job.HelloJob : param, key:msg, value:Hello Quartz
2021-10-01 13:09:09.000 INFO 38484 --- [duler_Worker-10] t.pdai.springboot.quartz.job.HelloJob : Hello Job执行时间: Wed Oct 27 13:09:09 CST 2021
2021-10-01 13:09:10.001 INFO 38484 --- [eduler_Worker-1] t.pdai.springboot.quartz.job.HelloJob : param, key:msg, value:Hello Quartz
2021-10-01 13:09:10.002 INFO 38484 --- [eduler_Worker-1] t.pdai.springboot.quartz.job.HelloJob : Hello Job执行时间: Wed Oct 27 13:09:10 CST 2021
2021-10-01 13:09:11.014 INFO 38484 --- [eduler_Worker-2] t.pdai.springboot.quartz.job.HelloJob : param, key:msg, value:Hello Quartz
2021-10-01 13:09:11.014 INFO 38484 --- [eduler_Worker-2] t.pdai.springboot.quartz.job.HelloJob : Hello Job执行时间: Wed Oct 27 13:09:11 CST 2021
复制代码
本例将展示quartz实现基于数据库的分布式任务管理;和控制job生命周期。
整体项目结构如下;
<?xml version=;1.0; encoding=;UTF-8;?>
<project xmlns=;http://maven.apache.org/POM/4.0.0;
xmlns:xsi=;http://www.w3.org/2001/XMLSchema-instance;
xsi:schemaLocation=;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd;>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>tech.pdai</groupId>
<artifactId>423-springboot-demo-schedule-quartz-cluster</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.42</version><!--$NO-MVN-MAN-VER$-->
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.0.0</version>
</dependency>
</dependencies>
</project>
复制代码
创建Schema
需要提前在MySQL中创建schema: quartz_jobs
#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;
# DROP TABLE IF EXISTS QRTZ_TASK_HISTORY;
CREATE TABLE QRTZ_JOB_DETAILS(
SCHED_NAME VARCHAR(120) NOT NULL,
JOB_NAME VARCHAR(200) NOT NULL,
JOB_GROUP VARCHAR(200) NOT NULL,
DESCRIPTION VARCHAR(250) NULL,
JOB_CLASS_NAME VARCHAR(250) NOT NULL,
IS_DURABLE VARCHAR(1) NOT NULL,
IS_NONCONCURRENT VARCHAR(1) NOT NULL,
IS_UPDATE_DATA VARCHAR(1) NOT NULL,
REQUESTS_RECOVERY VARCHAR(1) NOT NULL,
JOB_DATA BLOB NULL,
PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP))
ENGINE=InnoDB;
CREATE TABLE QRTZ_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
JOB_NAME VARCHAR(200) NOT NULL,
JOB_GROUP VARCHAR(200) NOT NULL,
DESCRIPTION VARCHAR(250) NULL,
NEXT_FIRE_TIME BIGINT(13) NULL,
PREV_FIRE_TIME BIGINT(13) NULL,
PRIORITY INTEGER NULL,
TRIGGER_STATE VARCHAR(16) NOT NULL,
TRIGGER_TYPE VARCHAR(8) NOT NULL,
START_TIME BIGINT(13) NOT NULL,
END_TIME BIGINT(13) NULL,
CALENDAR_NAME VARCHAR(200) NULL,
MISFIRE_INSTR SMALLINT(2) NULL,
JOB_DATA BLOB NULL,
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))
ENGINE=InnoDB;
CREATE TABLE QRTZ_SIMPLE_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
REPEAT_COUNT BIGINT(7) NOT NULL,
REPEAT_INTERVAL BIGINT(12) NOT NULL,
TIMES_TRIGGERED BIGINT(10) NOT NULL,
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))
ENGINE=InnoDB;
CREATE TABLE QRTZ_CRON_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
CRON_EXPRESSION VARCHAR(120) NOT NULL,
TIME_ZONE_ID VARCHAR(80),
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))
ENGINE=InnoDB;
CREATE TABLE QRTZ_SIMPROP_TRIGGERS
(
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
STR_PROP_1 VARCHAR(512) NULL,
STR_PROP_2 VARCHAR(512) NULL,
STR_PROP_3 VARCHAR(512) NULL,
INT_PROP_1 INT NULL,
INT_PROP_2 INT NULL,
LONG_PROP_1 BIGINT NULL,
LONG_PROP_2 BIGINT NULL,
DEC_PROP_1 NUMERIC(13,4) NULL,
DEC_PROP_2 NUMERIC(13,4) NULL,
BOOL_PROP_1 VARCHAR(1) NULL,
BOOL_PROP_2 VARCHAR(1) NULL,
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))
ENGINE=InnoDB;
CREATE TABLE QRTZ_BLOB_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
BLOB_DATA BLOB NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
INDEX (SCHED_NAME,TRIGGER_NAME, TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
ENGINE=InnoDB;
CREATE TABLE QRTZ_CALENDARS (
SCHED_NAME VARCHAR(120) NOT NULL,
CALENDAR_NAME VARCHAR(200) NOT NULL,
CALENDAR BLOB NOT NULL,
PRIMARY KEY (SCHED_NAME,CALENDAR_NAME))
ENGINE=InnoDB;
CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP))
ENGINE=InnoDB;
CREATE TABLE QRTZ_FIRED_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
ENTRY_ID VARCHAR(95) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
INSTANCE_NAME VARCHAR(200) NOT NULL,
FIRED_TIME BIGINT(13) NOT NULL,
SCHED_TIME BIGINT(13) NOT NULL,
PRIORITY INTEGER NOT NULL,
STATE VARCHAR(16) NOT NULL,
JOB_NAME VARCHAR(200) NULL,
JOB_GROUP VARCHAR(200) NULL,
IS_NONCONCURRENT VARCHAR(1) NULL,
REQUESTS_RECOVERY VARCHAR(1) NULL,
PRIMARY KEY (SCHED_NAME,ENTRY_ID))
ENGINE=InnoDB;
CREATE TABLE QRTZ_SCHEDULER_STATE (
SCHED_NAME VARCHAR(120) NOT NULL,
INSTANCE_NAME VARCHAR(200) NOT NULL,
LAST_CHECKIN_TIME BIGINT(13) NOT NULL,
CHECKIN_INTERVAL BIGINT(13) NOT NULL,
PRIMARY KEY (SCHED_NAME,INSTANCE_NAME))
ENGINE=InnoDB;
CREATE TABLE QRTZ_LOCKS (
SCHED_NAME VARCHAR(120) NOT NULL,
LOCK_NAME VARCHAR(40) NOT NULL,
PRIMARY KEY (SCHED_NAME,LOCK_NAME))
ENGINE=InnoDB;
CREATE TABLE QRTZ_TASK_HISTORY (
SCHED_NAME VARCHAR(120) NOT NULL,
INSTANCE_ID VARCHAR(200) NOT NULL,
FIRE_ID VARCHAR(95) NOT NULL,
TASK_NAME VARCHAR(200) NULL,
TASK_GROUP VARCHAR(200) NULL,
FIRED_TIME BIGINT(13) NULL,
FIRED_WAY VARCHAR(8) NULL,
COMPLETE_TIME BIGINT(13) NULL,
EXPEND_TIME BIGINT(13) NULL,
REFIRED INT NULL,
EXEC_STATE VARCHAR(10) NULL,
LOG TEXT NULL,
PRIMARY KEY (FIRE_ID)
)ENGINE=InnoDB;
CREATE INDEX IDX_QRTZ_J_REQ_RECOVERY ON QRTZ_JOB_DETAILS(SCHED_NAME,REQUESTS_RECOVERY);
CREATE INDEX IDX_QRTZ_J_GRP ON QRTZ_JOB_DETAILS(SCHED_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_T_J ON QRTZ_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_T_JG ON QRTZ_TRIGGERS(SCHED_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_T_C ON QRTZ_TRIGGERS(SCHED_NAME,CALENDAR_NAME);
CREATE INDEX IDX_QRTZ_T_G ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP);
CREATE INDEX IDX_QRTZ_T_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_T_N_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_T_N_G_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_T_NEXT_FIRE_TIME ON QRTZ_TRIGGERS(SCHED_NAME,NEXT_FIRE_TIME);
CREATE INDEX IDX_QRTZ_T_NFT_ST ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE,NEXT_FIRE_TIME);
CREATE INDEX IDX_QRTZ_T_NFT_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME);
CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE_GRP ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_FT_TRIG_INST_NAME ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME);
CREATE INDEX IDX_QRTZ_FT_INST_JOB_REQ_RCVRY ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME,REQUESTS_RECOVERY);
CREATE INDEX IDX_QRTZ_FT_J_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_FT_JG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_FT_T_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP);
CREATE INDEX IDX_QRTZ_FT_TG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_GROUP);
CREATE INDEX IDX_QRTZ_TK_S ON QRTZ_TASK_HISTORY(SCHED_NAME);
commit;
复制代码
application.yml
spring:
datasource:
url: jdbc:mysql://localhost:3306/quartz_jobs?useUnicode=true&useSSL=false
username: root
password: xxxxxxxx
driver-class-name: com.mysql.jdbc.Driver
quartz:
#相关属性配置
properties:
org:
quartz:
scheduler:
instanceName: clusteredScheduler
instanceId: AUTO
jobStore:
class: org.quartz.impl.jdbcjobstore.JobStoreTX
driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
tablePrefix: QRTZ_
isClustered: true
clusterCheckinInterval: 10000
useProperties: false
threadPool:
class: org.quartz.simpl.SimpleThreadPool
threadCount: 10
threadPriority: 5
threadsInheritContextClassLoaderOfInitializingThread: true
#数据库方式
job-store-type: jdbc
复制代码
定义JobDetails实体
/**
* ;author pdai
*
*/
;Data
public class JobDetails{
private String cronExpression;
private String jobClassName;
private String triggerGroupName;
private String triggerName;
private String jobGroupName;
private String jobName;
private Date nextFireTime;
private Date previousFireTime;
private Date startTime;
private String timeZone;
private String status;
}
复制代码
Job管理类
package tech.pdai.springboot.quartz.cluster.manager;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.DateBuilder;
import org.quartz.DateBuilder.IntervalUnit;
import org.quartz.Job;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.quartz.impl.matchers.GroupMatcher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.stereotype.Component;
import tech.pdai.springboot.quartz.cluster.entity.JobDetails;
/**
* ;author pdai
*/
;Component
public class QuartzManager {
;Autowired
private Scheduler sched;
/**
* 创建or更新任务;存在则更新不存在创建
*
* ;param jobClass 任务类
* ;param jobName 任务名称
* ;param jobGroupName 任务组名称
* ;param jobCron cron表达式
*/
public void addOrUpdateJob(Class<? extends QuartzJobBean> jobClass, String jobName, String jobGroupName, String jobCron) {
try {
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroupName);
CronTrigger trigger = (CronTrigger) sched.getTrigger(triggerKey);
if (trigger==null) {
addJob(jobClass, jobName, jobGroupName, jobCron);
} else {
if (trigger.getCronExpression().equals(jobCron)) {
return;
}
updateJob(jobName, jobGroupName, jobCron);
}
} catch (SchedulerException e) {
e.printStackTrace();
}
}
/**
* 增加一个job
*
* ;param jobClass 任务实现类
* ;param jobName 任务名称
* ;param jobGroupName 任务组名
* ;param jobCron cron表达式(如;0/5 * * * * ? )
*/
public void addJob(Class<? extends QuartzJobBean> jobClass, String jobName, String jobGroupName, String jobCron) {
try {
JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName).build();
Trigger trigger = TriggerBuilder.newTrigger().withIdentity(jobName, jobGroupName)
.startAt(DateBuilder.futureDate(1, IntervalUnit.SECOND))
.withSchedule(CronScheduleBuilder.cronSchedule(jobCron)).startNow().build();
sched.scheduleJob(jobDetail, trigger);
if (!sched.isShutdown()) {
sched.start();
}
} catch (SchedulerException e) {
e.printStackTrace();
}
}
/**
* ;param jobClass
* ;param jobName
* ;param jobGroupName
* ;param jobTime
*/
public void addJob(Class<? extends Job> jobClass, String jobName, String jobGroupName, int jobTime) {
addJob(jobClass, jobName, jobGroupName, jobTime, -1);
}
public void addJob(Class<? extends Job> jobClass, String jobName, String jobGroupName, int jobTime, int jobTimes) {
try {
JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName)// 任务名称和组构成任务key
.build();
// 使用simpleTrigger规则
Trigger trigger;
if (jobTimes < 0) {
trigger = TriggerBuilder.newTrigger().withIdentity(jobName, jobGroupName)
.withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(1).withIntervalInSeconds(jobTime))
.startNow().build();
} else {
trigger = TriggerBuilder
.newTrigger().withIdentity(jobName, jobGroupName).withSchedule(SimpleScheduleBuilder
.repeatSecondlyForever(1).withIntervalInSeconds(jobTime).withRepeatCount(jobTimes))
.startNow().build();
}
sched.scheduleJob(jobDetail, trigger);
if (!sched.isShutdown()) {
sched.start();
}
} catch (SchedulerException e) {
e.printStackTrace();
}
}
public void updateJob(String jobName, String jobGroupName, String jobTime) {
try {
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroupName);
CronTrigger trigger = (CronTrigger) sched.getTrigger(triggerKey);
trigger = trigger.getTriggerBuilder().withIdentity(triggerKey)
.withSchedule(CronScheduleBuilder.cronSchedule(jobTime)).build();
// 重启触发器
sched.rescheduleJob(triggerKey, trigger);
} catch (SchedulerException e) {
e.printStackTrace();
}
}
/**
* 删除任务一个job
*
* ;param jobName 任务名称
* ;param jobGroupName 任务组名
*/
public void deleteJob(String jobName, String jobGroupName) {
try {
sched.pauseTrigger(TriggerKey.triggerKey(jobName, jobGroupName));
sched.unscheduleJob(TriggerKey.triggerKey(jobName, jobGroupName));
sched.deleteJob(new JobKey(jobName, jobGroupName));
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 暂停一个job
*
* ;param jobName
* ;param jobGroupName
*/
public void pauseJob(String jobName, String jobGroupName) {
try {
JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
sched.pauseJob(jobKey);
} catch (SchedulerException e) {
e.printStackTrace();
}
}
/**
* 恢复一个job
*
* ;param jobName
* ;param jobGroupName
*/
public void resumeJob(String jobName, String jobGroupName) {
try {
JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
sched.resumeJob(jobKey);
} catch (SchedulerException e) {
e.printStackTrace();
}
}
/**
* 立即执行一个job
*
* ;param jobName
* ;param jobGroupName
*/
public void runAJobNow(String jobName, String jobGroupName) {
try {
JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
sched.triggerJob(jobKey);
} catch (SchedulerException e) {
e.printStackTrace();
}
}
public PageInfo<JobDetails> queryAllJobBean(int pageNum, int pageSize) {
PageHelper.startPage(pageNum, pageSize);
List<JobDetails> jobList = null;
try {
GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();
Set<JobKey> jobKeys = sched.getJobKeys(matcher);
jobList = new ArrayList<>();
for (JobKey jobKey : jobKeys) {
List<? extends Trigger> triggers = sched.getTriggersOfJob(jobKey);
for (Trigger trigger : triggers) {
JobDetails jobDetails = new JobDetails();
if (trigger instanceof CronTrigger) {
CronTrigger cronTrigger = (CronTrigger) trigger;
jobDetails.setCronExpression(cronTrigger.getCronExpression());
jobDetails.setTimeZone(cronTrigger.getTimeZone().getDisplayName());
}
jobDetails.setTriggerGroupName(trigger.getKey().getName());
jobDetails.setTriggerName(trigger.getKey().getGroup());
jobDetails.setJobGroupName(jobKey.getGroup());
jobDetails.setJobName(jobKey.getName());
jobDetails.setStartTime(trigger.getStartTime());
jobDetails.setJobClassName(sched.getJobDetail(jobKey).getJobClass().getName());
jobDetails.setNextFireTime(trigger.getNextFireTime());
jobDetails.setPreviousFireTime(trigger.getPreviousFireTime());
jobDetails.setStatus(sched.getTriggerState(trigger.getKey()).name());
jobList.add(jobDetails);
}
}
} catch (SchedulerException e) {
e.printStackTrace();
}
return new PageInfo<>(jobList);
}
/**
* 获取所有计划中的任务列表
*
* ;return
*/
public List<Map<String, Object>> queryAllJob() {
List<Map<String, Object>> jobList = null;
try {
GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();
Set<JobKey> jobKeys = sched.getJobKeys(matcher);
jobList = new ArrayList<>();
for (JobKey jobKey : jobKeys) {
List<? extends Trigger> triggers = sched.getTriggersOfJob(jobKey);
for (Trigger trigger : triggers) {
Map<String, Object> map = new HashMap<>();
map.put(;jobName;, jobKey.getName());
map.put(;jobGroupName;, jobKey.getGroup());
map.put(;description;, ;trigger:; ; trigger.getKey());
Trigger.TriggerState triggerState = sched.getTriggerState(trigger.getKey());
map.put(;jobStatus;, triggerState.name());
if (trigger instanceof CronTrigger) {
CronTrigger cronTrigger = (CronTrigger) trigger;
String cronExpression = cronTrigger.getCronExpression();
map.put(;jobTime;, cronExpression);
}
jobList.add(map);
}
}
} catch (SchedulerException e) {
e.printStackTrace();
}
return jobList;
}
/**
* 获取所有正在运行的job
*
* ;return
*/
public List<Map<String, Object>> queryRunJon() {
List<Map<String, Object>> jobList = null;
try {
List<JobExecutionContext> executingJobs = sched.getCurrentlyExecutingJobs();
jobList = new ArrayList<>(executingJobs.size());
for (JobExecutionContext executingJob : executingJobs) {
Map<String, Object> map = new HashMap<>();
JobDetail jobDetail = executingJob.getJobDetail();
JobKey jobKey = jobDetail.getKey();
Trigger trigger = executingJob.getTrigger();
map.put(;jobName;, jobKey.getName());
map.put(;jobGroupName;, jobKey.getGroup());
map.put(;description;, ;trigger:; ; trigger.getKey());
Trigger.TriggerState triggerState = sched.getTriggerState(trigger.getKey());
map.put(;jobStatus;, triggerState.name());
if (trigger instanceof CronTrigger) {
CronTrigger cronTrigger = (CronTrigger) trigger;
String cronExpression = cronTrigger.getCronExpression();
map.put(;jobTime;, cronExpression);
}
jobList.add(map);
}
} catch (SchedulerException e) {
e.printStackTrace();
}
return jobList;
}
}
复制代码
Job控制器接口
package tech.pdai.springboot.quartz.cluster.controller;
import java.util.HashMap;
import java.util.Map;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import tech.pdai.springboot.quartz.cluster.entity.JobDetails;
import tech.pdai.springboot.quartz.cluster.manager.QuartzManager;
/**
* ;author pdai
*/
;RestController
;RequestMapping(value = ;/job;)
public class JobController {
;Autowired
private QuartzManager qtzManager;
;SuppressWarnings(;unchecked;)
private static Class<? extends QuartzJobBean> getClass(String classname) throws Exception {
Class<?> class1 = Class.forName(classname);
return (Class<? extends QuartzJobBean>) class1;
}
/**
* ;param jobClassName
* ;param jobGroupName
* ;param cronExpression
* ;throws Exception
*/
;PostMapping(value = ;/addjob;)
public void addjob(;RequestParam(value = ;jobClassName;) String jobClassName,
;RequestParam(value = ;jobGroupName;) String jobGroupName,
;RequestParam(value = ;cronExpression;) String cronExpression) throws Exception {
qtzManager.addOrUpdateJob(getClass(jobClassName), jobClassName, jobGroupName, cronExpression);
}
/**
* ;param jobClassName
* ;param jobGroupName
* ;throws Exception
*/
;PostMapping(value = ;/pausejob;)
public void pausejob(;RequestParam(value = ;jobClassName;) String jobClassName,
;RequestParam(value = ;jobGroupName;) String jobGroupName) throws Exception {
qtzManager.pauseJob(jobClassName, jobGroupName);
}
/**
* ;param jobClassName
* ;param jobGroupName
* ;throws Exception
*/
;PostMapping(value = ;/resumejob;)
public void resumejob(;RequestParam(value = ;jobClassName;) String jobClassName,
;RequestParam(value = ;jobGroupName;) String jobGroupName) throws Exception {
qtzManager.resumeJob(jobClassName, jobGroupName);
}
/**
* ;param jobClassName
* ;param jobGroupName
* ;param cronExpression
* ;throws Exception
*/
;PostMapping(value = ;/reschedulejob;)
public void rescheduleJob(;RequestParam(value = ;jobClassName;) String jobClassName,
;RequestParam(value = ;jobGroupName;) String jobGroupName,
;RequestParam(value = ;cronExpression;) String cronExpression) throws Exception {
qtzManager.addOrUpdateJob(getClass(jobClassName), jobClassName, jobGroupName, cronExpression);
}
/**
* ;param jobClassName
* ;param jobGroupName
* ;throws Exception
*/
;PostMapping(value = ;/deletejob;)
public void deletejob(;RequestParam(value = ;jobClassName;) String jobClassName,
;RequestParam(value = ;jobGroupName;) String jobGroupName) throws Exception {
qtzManager.deleteJob(jobClassName, jobGroupName);
}
/**
* ;param pageNum
* ;param pageSize
* ;return
*/
;GetMapping(value = ;/queryjob;)
public Map<String, Object> queryjob(;RequestParam(value = ;pageNum;) Integer pageNum,
;RequestParam(value = ;pageSize;) Integer pageSize) {
PageInfo<JobDetails> jobAndTrigger = qtzManager.queryAllJobBean(pageNum, pageSize);
Map<String, Object> map = new HashMap<String, Object>();
map.put(;JobAndTrigger;, jobAndTrigger);
map.put(;number;, jobAndTrigger.getTotal());
return map;
}
}
复制代码
定义具体的Job
package tech.pdai.springboot.quartz.cluster.job;
import java.util.Date;
import lombok.extern.slf4j.Slf4j;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;
;Slf4j
public class HelloJob extends QuartzJobBean {
;Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
// get parameters
context.getJobDetail().getJobDataMap().forEach(
(k, v) -> log.info(;param, key:{}, value:{};, k, v)
);
// your logics
log.info(;Hello Job执行时间: ; ; new Date());
}
}
复制代码
简单用VueJS 写个页面测试
<!DOCTYPE html>
<html>
<head>
<meta charset=;UTF-8;>
<title>QuartzDemo</title>
<link rel=;stylesheet; href=;https://unpkg.com/element-ui;2.0.5/lib/theme-chalk/index.css;>
<script src=;https://unpkg.com/vue/dist/vue.js;></script>
<script src=;http://cdn.bootcss.com/vue-resource/1.3.4/vue-resource.js;></script>
<script src=;https://unpkg.com/element-ui;2.0.5/lib/index.js;></script>
<style>
#top {
background:#20A0FF;
padding:5px;
Overflow:hidden
}
</style>
</head>
<body>
<div id=;test;>
<div id=;top;>
<el-button type=;text; ;click=;search; style=;color:white;>查询</el-button>
<el-button type=;text; ;click=;handleadd; style=;color:white;>添加</el-button>
</span>
</div>
<br/>
<div style=;margin-top:15px;>
<el-table
ref=;testTable;
:data=;tableData;
style=;width:100%
border
>
<el-table-column
prop=;status;
label=;任务状态;
sortable
show-overflow-tooltip>
</el-table-column>
<el-table-column
prop=;jobName;
label=;任务名称;
sortable
show-overflow-tooltip>
</el-table-column>
<el-table-column
prop=;jobGroupName;
label=;任务所在组;
sortable>
</el-table-column>
<el-table-column
prop=;jobClassName;
label=;任务类名;
sortable>
</el-table-column>
<el-table-column
prop=;triggerName;
label=;触发器名称;
sortable>
</el-table-column>
<el-table-column
prop=;triggerGroupName;
label=;触发器所在组;
sortable>
</el-table-column>
<el-table-column
prop=;cronExpression;
label=;表达式;
sortable>
</el-table-column>
<el-table-column
prop=;timeZone;
label=;时区;
sortable>
</el-table-column>
<el-table-column label=;操作; width=;300;>
<template scope=;scope;>
<el-button
size=;small;
type=;warning;
;click=;handlePause(scope.$index, scope.row);>暂停</el-button>
<el-button
size=;small;
type=;info;
;click=;handleResume(scope.$index, scope.row);>恢复</el-button>
<el-button
size=;small;
type=;danger;
;click=;handleDelete(scope.$index, scope.row);>删除</el-button>
<el-button
size=;small;
type=;success;
;click=;handleUpdate(scope.$index, scope.row);>修改</el-button>
</template>
</el-table-column>
</el-table>
<div align=;center;>
<el-pagination
;size-change=;handleSizeChange;
;current-change=;handleCurrentChange;
:current-page=;currentPage;
:page-sizes=;[10, 20, 30, 40];
:page-size=;pagesize;
layout=;total, sizes, prev, pager, next, jumper;
:total=;totalCount;>
</el-pagination>
</div>
</div>
<el-dialog title=;添加任务; :visible.sync=;dialogFormVisible;>
<el-form :model=;form;>
<el-form-item label=;任务名称; label-width=;120px; style=;width:35%>
<el-input v-model=;form.jobName; auto-complete=;off;></el-input>
</el-form-item>
<el-form-item label=;任务分组; label-width=;120px; style=;width:35%>
<el-input v-model=;form.jobGroup; auto-complete=;off;></el-input>
</el-form-item>
<el-form-item label=;表达式; label-width=;120px; style=;width:35%>
<el-input v-model=;form.cronExpression; auto-complete=;off;></el-input>
</el-form-item>
</el-form>
<div slot=;footer; class=;dialog-footer;>
<el-button ;click=;dialogFormVisible = false;>取 消</el-button>
<el-button type=;primary; ;click=;add;>确 定</el-button>
</div>
</el-dialog>
<el-dialog title=;修改任务; :visible.sync=;updateFormVisible;>
<el-form :model=;updateform;>
<el-form-item label=;表达式; label-width=;120px; style=;width:35%>
<el-input v-model=;updateform.cronExpression; auto-complete=;off;></el-input>
</el-form-item>
</el-form>
<div slot=;footer; class=;dialog-footer;>
<el-button ;click=;updateFormVisible = false;>取 消</el-button>
<el-button type=;primary; ;click=;update;>确 定</el-button>
</div>
</el-dialog>
</div>
<footer align=;center;>
<p>© Quartz 任务管理</p>
</footer>
<script>
var vue = new Vue({
el:;#test;,
data: {
//表格当前页数据
tableData: [],
//请求的URL
url:;job/queryjob;,
//默认每页数据量
pagesize: 10,
//当前页码
currentPage: 1,
//查询的页码
start: 1,
//默认数据总数
totalCount: 1000,
//添加对话框默认可见性
dialogFormVisible: false,
//修改对话框默认可见性
updateFormVisible: false,
//提交的表单
form: {
jobName: ;;,
jobGroup: ;;,
cronExpression: ;;,
},
updateform: {
jobName: ;;,
jobGroup: ;;,
cronExpression: ;;,
},
},
methods: {
//从服务器读取数据
loadData: function(pageNum, pageSize){
this.$http.get(;job/queryjob?; ; ;pageNum=; ; pageNum ; ;&pageSize=; ; pageSize).then(function(res){
console.log(res)
this.tableData = res.body.JobAndTrigger.list;
this.totalCount = res.body.number;
},function(){
console.log(;failed;);
});
},
//单行删除
handleDelete: function(index, row) {
this.$http.post(;job/deletejob;,{;jobClassName;:row.jobName,;jobGroupName;:row.jobGroupName},{emulateJSON: true}).then(function(res){
this.loadData( this.currentPage, this.pagesize);
},function(){
console.log(;failed;);
});
},
//暂停任务
handlePause: function(index, row){
this.$http.post(;job/pausejob;,{;jobClassName;:row.jobName,;jobGroupName;:row.jobGroupName},{emulateJSON: true}).then(function(res){
this.loadData( this.currentPage, this.pagesize);
},function(){
console.log(;failed;);
});
},
//恢复任务
handleResume: function(index, row){
this.$http.post(;job/resumejob;,{;jobClassName;:row.jobName,;jobGroupName;:row.jobGroupName},{emulateJSON: true}).then(function(res){
this.loadData( this.currentPage, this.pagesize);
},function(){
console.log(;failed;);
});
},
//搜索
search: function(){
this.loadData(this.currentPage, this.pagesize);
},
//弹出对话框
handleadd: function(){
this.dialogFormVisible = true;
},
//添加
add: function(){
this.$http.post(;job/addjob;,{;jobClassName;:this.form.jobName,;jobGroupName;:this.form.jobGroup,;cronExpression;:this.form.cronExpression},{emulateJSON: true}).then(function(res){
this.loadData(this.currentPage, this.pagesize);
this.dialogFormVisible = false;
},function(){
console.log(;failed;);
});
},
//更新
handleUpdate: function(index, row){
console.log(row)
this.updateFormVisible = true;
this.updateform.jobName = row.jobClassName;
this.updateform.jobGroup = row.jobGroupName;
},
//更新任务
update: function(){
this.$http.post
(;job/reschedulejob;,
{;jobClassName;:this.updateform.jobName,
;jobGroupName;:this.updateform.jobGroup,
;cronExpression;:this.updateform.cronExpression
},{emulateJSON: true}
).then(function(res){
this.loadData(this.currentPage, this.pagesize);
this.updateFormVisible = false;
},function(){
console.log(;failed;);
});
},
//每页显示数据量变更
handleSizeChange: function(val) {
this.pagesize = val;
this.loadData(this.currentPage, this.pagesize);
},
//页码变更
handleCurrentChange: function(val) {
this.currentPage = val;
this.loadData(this.currentPage, this.pagesize);
},
},
});
//载入数据
vue.loadData(vue.currentPage, vue.pagesize);
</script>
</body>
</html>
复制代码
(PS: 这里的任务名称需要改成你自己的完整类名称)
展示正在运行的Jobs:
增加新的Job:
Jobs持久化在数据库:
github.com/realpdai/te…
告别碎片化学习;无套路一站式体系化学习后端开发: Java 全栈知识体系 https://pdai.tech
来源;https://juejin.cn/post/7126687148371083294#Vue3---Pinia-状态管理(环境搭建安装及各属性使用教程)详细使用教程
女神联盟怎么召唤3个宠物同时出战?-女神联盟召唤3个宠物同时出战教程攻略