最为罕用定时工作框架是Quartz,并且Spring也集成了Quartz的框架,Quartz不仅反对单实例形式还反对分布式形式。本文次要介绍Quartz,根底的Quartz的集成案例本,以及实现基于数据库的分布式工作治理和管制job生命周期。@pdai
  • SpringBoot定时工作 - 根底quartz实现形式

    • 筹备知识点

      • 什么是Quartz
      • Quartz的体系结构
      • 什么是Quartz长久化
    • 实现案例 - 单实例形式
    • 实现案例 - 分布式形式

      • 后端实现
      • 前端实现
      • 测试成果
    • 示例源码
    • 参考文章

筹备知识点

须要理解罕用的Quartz框架。

什么是Quartz

起源百度百科, 官网地址:http://www.quartz-scheduler.org/

Quartz是OpenSymphony开源组织在Job scheduling畛域又一个开源我的项目,它能够与J2EE与J2SE应用程序相结合也能够独自应用。Quartz能够用来创立简略或为运行十个,百个,甚至是好几万个Jobs这样简单的程序。Jobs能够做成规范的Java组件或 EJBs。

它的特点如下

  • 纯java实现,能够作为独立的应用程序,也能够嵌入在另一个独立式利用程序运行
  • 弱小的调度性能,Spring默认的调度框架,灵便可配置;
  • 作业长久化,调度环境长久化机制,能够保留并复原调度现场。零碎敞开数据不会失落;灵便的利用形式,能够任意定义触发器的调度时间表,反对工作和调度各种组合,组件式监听器、各种插件、线程池等性能,多种存储形式等;
  • 分布式和集群能力,能够被实例化,一个Quartz集群中的每个节点作为一个独立的Quartz应用,通过雷同的数据库表来感知到另一个Quartz利用

Quartz的体系结构

  • Job 示意一个工作,要执行的具体内容。
  • JobDetail 示意一个具体的可执行的调度程序,Job 是这个可执行程调度程序所要执行的内容,另外 JobDetail 还蕴含了这个任务调度的计划和策略。
  • Trigger 代表一个调度参数的配置,什么时候去调。
  • Scheduler 代表一个调度容器,一个调度容器中能够注册多个 JobDetail 和 Trigger。当 Trigger 与 JobDetail 组合,就能够被 Scheduler 容器调度了。

注: 上图来源于https://www.cnblogs.com/jijm1...

什么是Quartz长久化

  • 为什么要长久化

当程序忽然被中断时,如断电,内存超出时,很有可能造成工作的失落。 能够将调度信息存储到数据库外面,进行长久化,当程序被中断后,再次启动,依然会保留中断之前的数据,继续执行,而并不是从新开始。

  • Quartz提供了两种长久化形式

Quartz提供两种根本作业存储类型:

  1. RAMJobStore

在默认状况下Quartz将任务调度的运行信息保留在内存中,这种办法提供了最佳的性能,因为内存中数据拜访最快。不足之处是不足数据的持久性,当程序道路进行或零碎解体时,所有运行的信息都会失落。

  1. JobStoreTX

所有的工作信息都会保留到数据库中,能够管制事物,还有就是如果应用服务器敞开或者重启,工作信息都不会失落,并且能够复原因服务器敞开或者重启而导致执行失败的工作。

实现案例 - 单实例形式

本例将展现quartz实现单实例形式。
  • 引入POM依赖
<dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-quartz</artifactId></dependency>
  • 定义Job

只须要继承QuartzJobBean,并重载executeInternal办法即可定义你本人的Job执行逻辑。

@Slf4jpublic 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 */@Configurationpublic 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 WebApplicationContext2021-10-01 13:09:00.526  INFO 38484 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1424 ms2021-10-01 13:09:00.866  INFO 38484 --- [           main] org.quartz.impl.StdSchedulerFactory      : Using default implementation for ThreadExecutor2021-10-01 13:09:00.877  INFO 38484 --- [           main] org.quartz.core.SchedulerSignalerImpl    : Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl2021-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.22021-10-01 13:09:00.879  INFO 38484 --- [           main] org.quartz.core.QuartzScheduler          : JobFactory set to: org.springframework.scheduling.quartz.SpringBeanJobFactory@6075b2d32021-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 now2021-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 Quartz2021-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 20212021-10-01 13:09:01.001  INFO 38484 --- [eduler_Worker-2] t.pdai.springboot.quartz.job.HelloJob    : param, key:msg, value:Hello Quartz2021-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 20212021-10-01 13:09:02.000  INFO 38484 --- [eduler_Worker-3] t.pdai.springboot.quartz.job.HelloJob    : param, key:msg, value:Hello Quartz2021-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 20212021-10-01 13:09:03.000  INFO 38484 --- [eduler_Worker-4] t.pdai.springboot.quartz.job.HelloJob    : param, key:msg, value:Hello Quartz2021-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 20212021-10-01 13:09:04.001  INFO 38484 --- [eduler_Worker-5] t.pdai.springboot.quartz.job.HelloJob    : param, key:msg, value:Hello Quartz2021-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 20212021-10-01 13:09:05.002  INFO 38484 --- [eduler_Worker-6] t.pdai.springboot.quartz.job.HelloJob    : param, key:msg, value:Hello Quartz2021-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 20212021-10-01 13:09:06.000  INFO 38484 --- [eduler_Worker-7] t.pdai.springboot.quartz.job.HelloJob    : param, key:msg, value:Hello Quartz2021-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 20212021-10-01 13:09:07.002  INFO 38484 --- [eduler_Worker-8] t.pdai.springboot.quartz.job.HelloJob    : param, key:msg, value:Hello Quartz2021-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 20212021-10-01 13:09:08.002  INFO 38484 --- [eduler_Worker-9] t.pdai.springboot.quartz.job.HelloJob    : param, key:msg, value:Hello Quartz2021-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 20212021-10-01 13:09:09.000  INFO 38484 --- [duler_Worker-10] t.pdai.springboot.quartz.job.HelloJob    : param, key:msg, value:Hello Quartz2021-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 20212021-10-01 13:09:10.001  INFO 38484 --- [eduler_Worker-1] t.pdai.springboot.quartz.job.HelloJob    : param, key:msg, value:Hello Quartz2021-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 20212021-10-01 13:09:11.014  INFO 38484 --- [eduler_Worker-2] t.pdai.springboot.quartz.job.HelloJob    : param, key:msg, value:Hello Quartz2021-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生命周期。

整体我的项目构造如下:

后端实现

  • pom.xml
<?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 * */@Datapublic 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 */@Componentpublic 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;@Slf4jpublic 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>&copy; 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长久化在数据库:

示例源码

https://github.com/realpdai/t...

更多内容

辞别碎片化学习,无套路一站式体系化学习后端开发: Java 全栈常识体系 https://pdai.tech