自动化定时任务 分布式集成[集群] 定时自动漂移

自动化定时任务 分布式集成[集群] 定时自动漂移

前言
当你使用分布式系统时候,往往会使用集群,但是在集群模式中定时任务部署会遇到,俩个部署运行一个定时,这样就出现了数据安全性问题[数据插入多条记录,数据库死锁,数据不全等]
为了解决此问题,有俩种实现方案,一种使用Quartz组件集成自己项目,第二种就是使用开源框架xxljob等
这里我们介绍使用Quartz方式实现分布式自动化定时任务,这个非但可以实现定时执行任务,也可以随时调用一个业务层函数.哈哈.是不是很神奇
原理,Quartz默认是使用内存进行的任务调度,这样就使得集群不能共享一个资源,出现问题了.然后我们可以有俩种方式应对,1.redis[缓存数据库],2.数据库.
这里我们使用数据库方式进行,因为官方提供的嘛.比较好用,不然你还需要实现一个redis的调度类去做,很麻烦.
ok上代码…

定时控制类Controller层
crud+恢复+暂停+移除定时的操作

package com.techhero.base.system.controller.abs;

import com.techhero.base.system.service.abs.QuartzService;
import com.techhero.common.base.BaseController;
import com.techhero.common.model.abs.QuartzControl;
import com.techhero.common.utils.req.ResBean;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;

@RestController
@RequestMapping("/quartzMng")
public class QuartzController extends BaseController {
    
    @Resource
    private QuartzService quartzService;
    
    /*添加任务*/
    @PostMapping
    public ResBean addJob(@RequestBody QuartzControl quartzControl) {
        return quartzService.addJob(quartzControl);
    }
    
    /*获取任务列表*/
    @PostMapping("findListPage")
    public ResBean findListPage(@RequestBody QuartzControl quartzControl) {
        return quartzService.findListPage(quartzControl);
    }
    
    /*删除任务*/
    @DeleteMapping("{id}")
    public ResBean delJob(@PathVariable String id) {
        return quartzService.delJob(id);
    }
    
    /*修改任务*/
    @PutMapping
    public ResBean updateJob(@RequestBody QuartzControl quartzControl){
        return quartzService.updateJob(quartzControl);
    }
    
    /*启动任务*/
    @GetMapping("startJob/{id}")
    public ResBean startJob(@PathVariable String id){
        return quartzService.startJob(id);
    }
    
    /*暂停任务*/
    @GetMapping("pauseJob/{id}")
    public ResBean pauseJob(@PathVariable String id){
        return quartzService.pauseJob(id);
    }
    
    /*恢复任务*/
    @GetMapping("resumeJob/{id}")
    public ResBean resumeJob(@PathVariable String id){
        return quartzService.resumeJob(id);
    }
    
    
    
}

业务层
接口

package com.techhero.base.system.service.abs;

import com.techhero.common.model.abs.QuartzControl;
import com.techhero.common.utils.req.ResBean;

/*分布式石英任务管理*/
public interface QuartzService {
    
    /*添加*/
    ResBean addJob(QuartzControl quartzControl);
    
    /*查询*/
    ResBean findListPage(QuartzControl quartzControl);
    
    /*修改*/
    ResBean updateJob(QuartzControl quartzControl);
    
    /*删除*/
    ResBean delJob(String id);
    
    /*启动任务*/
    ResBean startJob(String id);
    
    /*暂停任务*/
    ResBean pauseJob(String id);
    
    /*恢复任务*/
    ResBean resumeJob(String id);
}

实现类

package com.techhero.base.system.service.abs.impl;

import com.github.pagehelper.PageInfo;
import com.techhero.base.system.mapper.abs.QuartzControlMapper;
import com.techhero.base.system.service.abs.QuartzDispatchService;
import com.techhero.base.system.service.abs.QuartzService;
import com.techhero.common.model.abs.QuartzControl;
import com.techhero.common.utils.req.ResBean;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

@Service
@Slf4j
public class QuartzServiceImpl implements QuartzService {
    
    @Resource
    private QuartzControlMapper quartzControlMapper;
    
    @Resource
    private QuartzDispatchService quartzDispatchService;
    
    
    /*添加任务*/
    @Override
    public ResBean addJob(QuartzControl quartzControl) {
        log.info("任务添加\n{}",quartzControl);
        /*默认为子系统未启动状态*/
        quartzControl.setJobState(0);
        int i = quartzControlMapper.insertSelective(quartzControl);
        log.info("任务添加完成....\n{}",quartzControl);
        return ResBean.addValid(i);
    }
    
    /*查询任务列表*/
    @Override
    public ResBean findListPage(QuartzControl quartzControl) {
        quartzControl.startPage();
        List<QuartzControl> quartzControls = this.quartzControlMapper.selectAll();
        return ResBean.success(new PageInfo<QuartzControl>(quartzControls));
    }
    
    /*修改任务*/
    @Override
    public ResBean updateJob(QuartzControl quartzControl) {
        
        /*先查询到原始的任务信息,将原始任务在子系统删除*/
        String id = quartzControl.getId();
        QuartzControl oldQuartzControl= quartzControlMapper.selectByPrimaryKey(id);
        quartzDispatchService.removeJob(oldQuartzControl);
        
        if(oldQuartzControl.getJobState().equals(1)){
            quartzControl.setJobState(1);
            /*当原始任务已经启动情况下*/
            String jobAddress = quartzDispatchService.updateJob(quartzControl);
            if (StringUtils.isNotBlank(jobAddress)) {
                quartzControl.setJobAddress(jobAddress);
            }
        }else{
            /*其他状态修改为*/
            quartzControl.setJobState(0);
            quartzControl.setJobAddress(null);
        }
        
        /*更新定时表数据*/
        int i = quartzControlMapper.updateByPrimaryKeySelective(quartzControl);
        return ResBean.addValid(i);
    }
    
    /*删除任务*/
    @Override
    public ResBean delJob(String id) {
        QuartzControl quartzControl = quartzControlMapper.selectByPrimaryKey(id);
        quartzDispatchService.removeJob(quartzControl);
        int i = quartzControlMapper.deleteByPrimaryKey(id);
        return ResBean.validCountBean(i);
    }
    
    /*启动任务*/
    @Override
    public ResBean startJob(String id) {
        QuartzControl quartzControl = quartzControlMapper.selectByPrimaryKey(id);
        String        jobAddress    = quartzDispatchService.startJob(quartzControl);
        int jobState=1;
        if(quartzControl.getJobType().equals(0)){
            jobState=0;
        }
        int           i             = quartzControlMapper.updateByPrimaryKeySelective(QuartzControl.builder().id(id).jobAddress(jobAddress).jobState(jobState).build());
        log.info("任务启动成功");
        return ResBean.validCountBean(i);
    }
    
    /*暂停任务*/
    @Override
    public ResBean pauseJob(String id) {
        QuartzControl quartzControl = quartzControlMapper.selectByPrimaryKey(id);
        quartzDispatchService.pauseJob(quartzControl);
        int           i             = quartzControlMapper.updateByPrimaryKeySelective(QuartzControl.builder().id(id).jobState(2).build());
        log.info("任务暂停成功");
        return ResBean.validCountBean(i);
    }
    
    /*恢复任务*/
    @Override
    public ResBean resumeJob(String id) {
        QuartzControl quartzControl = quartzControlMapper.selectByPrimaryKey(id);
        quartzDispatchService.resumeJob(quartzControl);
        int           i             = quartzControlMapper.updateByPrimaryKeySelective(QuartzControl.builder().id(id).jobState(1).build());
        log.info("任务恢复成功");
        return ResBean.validCountBean(i);
    }
    
}

任务调度类–由于有可能你的系统有很多子系统
所以这里专门做任务调度

接口

package com.techhero.base.system.service.abs;

import com.techhero.common.model.abs.QuartzControl;

/*任务调度service*/
public interface QuartzDispatchService {
    
    /*启动任务*/
    String startJob(QuartzControl quartzControl);
    
    /*移除任务*/
    void removeJob(QuartzControl quartzControl);
    
    /*修改任务*/
    String updateJob(QuartzControl quartzControl);
    
    /*暂停任务*/
    void pauseJob(QuartzControl quartzControl);
    
    /*恢复任务*/
    void resumeJob(QuartzControl quartzControl);
}

实现

package com.techhero.base.system.service.abs.impl;

import com.techhero.base.system.feigin.abs.TransDataQuartzDispatchFeign;
import com.techhero.base.system.service.abs.QuartzDispatchService;
import com.techhero.common.constant.ServiceNameConstant;
import com.techhero.common.model.abs.QuartzControl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

@Service
@Slf4j
public class QuartzDispatchServiceImpl implements QuartzDispatchService {
    
    @Resource
    private TransDataQuartzDispatchFeign transDataQuartzDispatchFeign;
    
    /*启动一个任务*/
    @Override
    public String startJob(QuartzControl quartzControl) {
        /*服务名:代表那个子系统[这个字段保存微服务名称]*/
        String serverName = quartzControl.getJobGroup();
        if(StringUtils.isNotBlank(serverName)){
            if(serverName.equals(ServiceNameConstant.TRANSDATA_SERVICE)){
                return transDataQuartzDispatchFeign.addAndStartJob(quartzControl);
            }
        }
        log.info("服务名称没有指定\n{}",quartzControl);
        return null;
    }
    
    /*删除一个任务*/
    @Override
    public void removeJob(QuartzControl quartzControl) {
        /*服务名:代表那个子系统[这个字段保存微服务名称]*/
        String serverName = quartzControl.getJobGroup();
        if(StringUtils.isNotBlank(serverName)){
            if(serverName.equals(ServiceNameConstant.TRANSDATA_SERVICE)){
                transDataQuartzDispatchFeign.removeJob(quartzControl);
            }
            return ;
        }
        log.info("服务名称没有指定\n{}",quartzControl);
    }
    
    /*修改任务*/
    @Override
    public String updateJob(QuartzControl quartzControl) {
        /*服务名:代表那个子系统[这个字段保存微服务名称]*/
        String serverName = quartzControl.getJobGroup();
        if(StringUtils.isNotBlank(serverName)){
            if(serverName.equals(ServiceNameConstant.TRANSDATA_SERVICE)){
                Integer jobState = quartzControl.getJobState();
                if(jobState==2){
                    /*子系统如果是暂停状态,则将此定时清除,后边需要人工启动这个定时*/
                    transDataQuartzDispatchFeign.removeJob(quartzControl);
                }else if(jobState==1){
                    /*子系统如果是启动状态,则之间调用修改*/
                   return transDataQuartzDispatchFeign.updateJob(quartzControl);
                }
            }
        }
        log.info("服务名称没有指定\n{}",quartzControl);
        return null;
    }
    
    /*暂停任务*/
    @Override
    public void pauseJob(QuartzControl quartzControl) {
        /*服务名:代表那个子系统[这个字段保存微服务名称]*/
        String serverName = quartzControl.getJobGroup();
        if(StringUtils.isNotBlank(serverName)){
            if(serverName.equals(ServiceNameConstant.TRANSDATA_SERVICE)){
                Integer jobState = quartzControl.getJobState();
                if(jobState==1){
                    /*只有在任务启动状态下时候才能暂停任务*/
                    transDataQuartzDispatchFeign.pauseJob(quartzControl);
                }
            }
        }
    }
    
    /*恢复任务*/
    @Override
    public void resumeJob(QuartzControl quartzControl) {
        /*服务名:代表那个子系统[这个字段保存微服务名称]*/
        String serverName = quartzControl.getJobGroup();
        if(StringUtils.isNotBlank(serverName)){
            if(serverName.equals(ServiceNameConstant.TRANSDATA_SERVICE)){
                Integer jobState = quartzControl.getJobState();
                if(jobState==2){
                    /*只有在任务启动状态下时候才能暂停任务*/
                    transDataQuartzDispatchFeign.resumeJob(quartzControl);
                }
            }
        }
    }
    
}

OK以上内容比较简单,其实就是做了一个定时任务的记录表crud 和远程调用子系统,让子系统执行一个定时任务

下边上集成时候的和一些核心类
实现方案,quartz是可以进行传递参数的,然后我们将service名称,和函数名称作为一个参数传递给子系统,子系统通过反射进行调用就行,所以没有必要所有类都实现JOB接口.只需要定义一个就行.

配置quartz 配置类

package com.techhero.common.bean.config.quartz;

import org.quartz.spi.JobFactory;
import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.scheduling.quartz.SpringBeanJobFactory;

import javax.sql.DataSource;
import java.util.Properties;

/**
 * quartz定时任务配置
 */
@Configuration
@ConditionalOnProperty(value = "task.switch",havingValue = "true")
@EnableScheduling
public class QuartzConfiguration {
    /**
     * 继承org.springframework.scheduling.quartz.SpringBeanJobFactory
     * 实现任务实例化方式
     *
     * 可以看到上面配置类中,AutowiringSpringBeanJobFactory我们继承了SpringBeanJobFactory类
     * 并且通过实现ApplicationContextAware接口获取ApplicationContext设置方法
     * 通过外部实例化时设置ApplicationContext实例对象,在createJobInstance方法内
     * 我们采用AutowireCapableBeanFactory来托管SpringBeanJobFactory类中createJobInstance方法返回的定时任务实例
     * 这样就可以在定时任务类内使用Spring Ioc相关的注解进行注入业务逻辑实例。
     */
    public static class AutowiringSpringBeanJobFactory extends SpringBeanJobFactory implements ApplicationContextAware {
        
        private transient AutowireCapableBeanFactory beanFactory;
        
        @Override
        public void setApplicationContext(final ApplicationContext context) {
            beanFactory = context.getAutowireCapableBeanFactory();
        }
        
        /**
         * 将job实例交给spring ioc托管
         * 我们在job实例实现类内可以直接使用spring注入的调用被spring ioc管理的实例
         */
        @Override
        protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
            final Object job = super.createJobInstance(bundle);
            /**
             * 将job实例交付给spring ioc
             */
            beanFactory.autowireBean(job);
            return job;
        }
    }
    
    /**
     * 配置任务工厂实例
     *
     * 任务工厂是在本章配置调度器时所需要的实例,我们通过jobFactory方法注入ApplicationContext实例
     * 来创建一个AutowiringSpringBeanJobFactory对象,并且将对象实例托管到Spring Ioc容器内。
     */
    @Bean
    public JobFactory jobFactory(ApplicationContext applicationContext) {
        /**
         * 采用自定义任务工厂 整合spring实例来完成构建任务
         * see {@link AutowiringSpringBeanJobFactory}
         */
        AutowiringSpringBeanJobFactory jobFactory = new AutowiringSpringBeanJobFactory();
        jobFactory.setApplicationContext(applicationContext);
        return jobFactory;
    }
    
    /**
     * 配置任务调度器
     * 使用项目数据源作为quartz数据源
     *
     * 在上面配置类中可以看到方法schedulerFactoryBean内自动注入了JobFactory实例,
     * 也就是我们自定义的AutowiringSpringBeanJobFactory任务工厂实例,
     * 调用SchedulerFactoryBean对象的setConfigLocation方法来设置quartz定时任务框架的基本配置
     *
     * @param jobFactory 自定义配置任务工厂
     * @param dataSource 数据源实例
     * @return SchedulerFactoryBean
     * @throws Exception
     */
    @Bean(destroyMethod = "destroy", autowire = Autowire.NO)
    public SchedulerFactoryBean schedulerFactoryBean(JobFactory jobFactory, DataSource dataSource) throws Exception {
        SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
        //将spring管理job自定义工厂交由调度器维护
        schedulerFactoryBean.setJobFactory(jobFactory);
        //设置覆盖已存在的任务
        schedulerFactoryBean.setOverwriteExistingJobs(true);
        //项目启动完成后,等待2秒后开始执行调度器初始化
        schedulerFactoryBean.setStartupDelay(2);
        //设置调度器自动运行
        schedulerFactoryBean.setAutoStartup(true);
        //设置数据源,使用与项目统一数据源
        schedulerFactoryBean.setDataSource(dataSource);
        //设置上下文spring bean name
        schedulerFactoryBean.setApplicationContextSchedulerContextKey("applicationContext");
        //设置配置文件位置
        //schedulerFactoryBean.setConfigLocation(new ClassPathResource("/quartz.properties"));
        setQuartzProperties(schedulerFactoryBean);
        return schedulerFactoryBean;
    }
    
    public void setQuartzProperties(SchedulerFactoryBean schedulerFactoryBean){
        Properties prop = new Properties();
        
        /*调度器实例名称*/
        prop.put("org.quartz.scheduler.instanceName","quartzScheduler");
        /*调度器实例编号自动生成*/
        prop.put("org.quartz.scheduler.instanceId","AUTO");
        /*持久化方式配置*/
        prop.put("org.quartz.jobStore.class","org.quartz.impl.jdbcjobstore.JobStoreTX");
        /*持久化方式配置数据驱动,ORACLE数据库*/
        prop.put("org.quartz.jobStore.driverDelegateClass","org.quartz.impl.jdbcjobstore.oracle.OracleDelegate");
        /*quartz相关数据表前缀名*/
        prop.put("org.quartz.jobStore.tablePrefix","QRTZ_");
        /*开启分布式部署*/
        prop.put("org.quartz.jobStore.isClustered","true");
        /*配置是否使用*/
        prop.put("org.quartz.jobStore.useProperties","false");
        /*分布式节点有效性检查时间间隔,单位:毫秒*/
        prop.put("org.quartz.jobStore.clusterCheckinInterval","20000");
        /*线程池实现类*/
        prop.put("org.quartz.threadPool.class","org.quartz.simpl.SimpleThreadPool");
        /*执行最大并发线程数量*/
        prop.put("org.quartz.threadPool.threadCount","20");
        /*线程优先级 不能大于9*/
        prop.put("org.quartz.threadPool.threadPriority","9");
        /*配置是否启动自动加载数据库内的定时任务*/
        prop.put("org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread","true");
    
        /*ID生成器*/
        /*prop.put("org.quartz.scheduler.instanceIdGenerator.class","org.quartz.simpl.HostnameInstanceIdGenerator");*/
        /*配置为守护线程,设置后任务将不会执行*/
        /*prop.put("org.quartz.threadPool.makeThreadsDaemons","true");*/
        
    }
    
    
}

上边读取配置文件有俩种方式.但是我觉得没有必要作为一个配置文件使用,不然每一个子系统还需要重复造轮子.所以这个配置直接写死就行,但是本人乐于助人,吧配置文件方式也在里面注释的写了一下
配置文件如下-放到resource下就行
匹配 //schedulerFactoryBean.setConfigLocation(new ClassPathResource("/quartz.properties")); 代码打开就行

#调度器实例名称
org.quartz.scheduler.instanceName = quartzScheduler

#调度器实例编号自动生成
org.quartz.scheduler.instanceId = AUTO

#示例ID生成器
#org.quartz.scheduler.instanceIdGenerator.class = org.quartz.simpl.HostnameInstanceIdGenerator

#持久化方式配置
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX

#持久化方式配置数据驱动,ORACLE数据库
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.oracle.OracleDelegate

#quartz相关数据表前缀名
org.quartz.jobStore.tablePrefix = QRTZ_

#开启分布式部署
org.quartz.jobStore.isClustered = true

#配置是否使用
org.quartz.jobStore.useProperties = false

#分布式节点有效性检查时间间隔,单位:毫秒
org.quartz.jobStore.clusterCheckinInterval = 20000

#线程池实现类
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool

#执行最大并发线程数量
org.quartz.threadPool.threadCount = 20

#线程优先级 不能大于9
org.quartz.threadPool.threadPriority = 9

#配置为守护线程,设置后任务将不会执行
#org.quartz.threadPool.makeThreadsDaemons=true

#配置是否启动自动加载数据库内的定时任务,默认true
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true

子系统 申请定时任务创建删除修改暂停恢复等controller

package com.techhero.common.bean.config.quartz;

import com.techhero.common.model.abs.QuartzControl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.ApplicationContext;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Date;

/*定时任务管理器*/
@Slf4j
@RestController
@RequestMapping("/quartz")
@ConditionalOnProperty(value = "task.switch",havingValue = "true")
public class QuartzManager {
    
    @Resource
    private Scheduler scheduler;
    
    @Resource
    private ApplicationContext applicationContext;
    
    /*服务器启动端口*/
    @Value("${server.port}")
    private String serverPort;
    
    /*
     * 工具函数,获取当前机器的IP地址和端口
     * [方便系统管理定时器回填目前执行的地址]
     */
    private String getAddress() {
        String startAddress = null;
        try {
            InetAddress ip4 = Inet4Address.getLocalHost();
            startAddress = ip4 + ":" + serverPort;
        } catch (UnknownHostException e) {
            log.error("[获取IP失败,运行异常]", e);
        }
        return startAddress;
    }
    
    /*拼装JobDetail*/
    private JobDetail getJobDetail(QuartzControl quartzControl) throws SchedulerException {
        /*任务名称*/
        String name = quartzControl.getJobName();
    
        /*任务所属分组*/
        String group = quartzControl.getJobGroup();
    
        JobDetail jobDetail = scheduler.getJobDetail(new JobKey(name, group));
        
        if(jobDetail==null){
            /*任务描述*/
            String jobDesc = quartzControl.getJobDesc();
    
            /*创建任务*/
            jobDetail = JobBuilder.newJob(LockerQuartzJob.class).withIdentity(name, group).withDescription(jobDesc).build();
    
            /*设定参数*/
            jobDetail.getJobDataMap().put("quartzControl", quartzControl);
        }
        
        return jobDetail;
    }
    
    /*间隔时间执行单位[秒]*/
    private Boolean exeIntervalTime(QuartzControl quartzControl) throws SchedulerException {
        /*cron表达式*/
        String cronExpression = quartzControl.getJobExpression();
        
        if(StringUtils.isBlank(cronExpression)){
            log.info("表达式不能为空\n{}",quartzControl);
            return false;
        }
        Integer seconds=0;
        try {
            seconds=Integer.valueOf(cronExpression);
        } catch (NumberFormatException e) {
            log.error("[任务表达式异常]\n{}",quartzControl, e);
            return false;
        }
    
        JobDetail jobDetail = getJobDetail(quartzControl);
    
        Trigger trigger = scheduler.getTrigger(TriggerKey.triggerKey(quartzControl.getJobName(), quartzControl.getJobGroup()));
        
        if(trigger==null){
            /*创建任务触发器*/
            trigger = TriggerBuilder.newTrigger()
                    .withIdentity(quartzControl.getJobName(), quartzControl.getJobGroup())
                    .startNow()
                    .withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(seconds))
                    .build();
            /*将触发器与任务绑定到调度器内*/
            scheduler.scheduleJob(jobDetail, trigger);
        }
        
        return true;
    }
    
    /*cron表达式执行*/
    private Boolean exeCron(QuartzControl quartzControl) throws SchedulerException {
        
        /*cron表达式*/
        String cronExpression = quartzControl.getJobExpression();
        
        if(StringUtils.isBlank(cronExpression)){
            return false;
        }
    
        JobDetail jobDetail = getJobDetail(quartzControl);
    
        Trigger trigger = scheduler.getTrigger(TriggerKey.triggerKey(quartzControl.getJobName(), quartzControl.getJobGroup()));
        if(trigger==null){
            /*创建任务触发器*/
            trigger = TriggerBuilder.newTrigger()
                    .withIdentity(quartzControl.getJobName(), quartzControl.getJobGroup())
                    .withSchedule(CronScheduleBuilder.cronSchedule(cronExpression.trim()))
                    .build();
            /*将触发器与任务绑定到调度器内*/
            scheduler.scheduleJob(jobDetail, trigger);
        }
       
        return true;
    }
    
    /*延时执行一次*/
    private Boolean exeOnce(QuartzControl quartzControl) throws SchedulerException {
        /*初始化执行时间*/
        String jobExpression = quartzControl.getJobExpression();
        Long   addTime       = 10L;
        try {
            addTime = Long.valueOf(jobExpression);
        } catch (NumberFormatException e) {
            log.error("[时间设定错误,默认使用10秒作为延时]", e);
            return false;
        }
        long startAtTime = 1000 * addTime;
    
        JobDetail jobDetail = getJobDetail(quartzControl);
        
        Trigger trigger = scheduler.getTrigger(TriggerKey.triggerKey(quartzControl.getJobName(), quartzControl.getJobGroup()));
        
        if(trigger==null){
            /*创建任务触发器*/
            trigger = TriggerBuilder.newTrigger()
                    .withIdentity(quartzControl.getJobName(), quartzControl.getJobGroup())
                    .startAt(new Date(startAtTime))
                    .build();
            /*将触发器与任务绑定到调度器内*/
            scheduler.scheduleJob(jobDetail, trigger);
        }
        return true;
    }
    
    /*添加任务*/
    @PostMapping("addAndStartJob")
    public String addAndStartJob(@RequestBody QuartzControl quartzControl) throws SchedulerException {
        log.info("正在添加且启动任务...\n{}",quartzControl);
        /*定时器执行方式*/
        Integer jobType = quartzControl.getJobType();
        Boolean flag=false;
        if (jobType == 0) {
            /*执行一次*/
            flag=exeOnce(quartzControl);
        } else if (jobType == 1) {
            /*cron表达式执行*/
            flag=exeCron(quartzControl);
        } else if (jobType == 2) {
            /*间隔时间执行单位[秒]*/
            flag=exeIntervalTime(quartzControl);
        }
       
        if(flag){
            String address = getAddress();
            log.info("添加且启动任务成功...\n{},{}",address,quartzControl);
            return address;
        }
        return null;
    }
    
    /*修改一个任务*/
    @PostMapping("updateJob")
    public String updateJob(@RequestBody QuartzControl quartzControl) throws SchedulerException{
        log.info("正在修改任务...\n{}",quartzControl);
        
        /*所谓修改任务其实就是将任务移除了,然后在新增启动*/
        removeJob(quartzControl);
        String ipAddress = addAndStartJob(quartzControl);
    
        log.info("修改任务成功...\n{}:{}",ipAddress,quartzControl);
        return ipAddress;
    }
    
    /*暂停任务*/
    @PostMapping("pauseJob")
    public void pauseJob(@RequestBody QuartzControl quartzControl) throws SchedulerException {
        try {
            log.info("正在暂停任务...\n{}",quartzControl);
            scheduler.pauseJob(JobKey.jobKey(quartzControl.getJobName(), quartzControl.getJobGroup()));
            log.info("完成暂停任务...\n{}",quartzControl);
        } catch (SchedulerException e) {
            log.error("暂停定时任务失败",e);
        }
    }
    
    /**
     * 恢复任务
     * @param quartzControl
     * @throws SchedulerException
     */
    @PostMapping("resumeJob")
    public void resumeJob(@RequestBody QuartzControl quartzControl)throws SchedulerException {
        try {
            log.info("恢复任务中...\n{}",quartzControl);
            scheduler.resumeJob(JobKey.jobKey(quartzControl.getJobName(), quartzControl.getJobGroup()));
            log.info("恢复任务完毕...\n{}",quartzControl);
        } catch (SchedulerException e) {
            log.error("恢复定时任务失败",e);
        }
    }
    
    /*移除任务*/
    @PostMapping("removeJob")
    public void removeJob(@RequestBody QuartzControl quartzControl) throws SchedulerException {
        try {
            log.info("删除任务中...\n{}",quartzControl);
            TriggerKey triggerKey = TriggerKey.triggerKey(quartzControl.getJobName(), quartzControl.getJobGroup());
            /*停止触发器*/
            scheduler.pauseTrigger(triggerKey);
            /*移除触发器*/
            scheduler.unscheduleJob(triggerKey);
            /*删除任务*/
            scheduler.deleteJob(JobKey.jobKey(quartzControl.getJobName(), quartzControl.getJobGroup()));
            log.info("删除任务完成...\n{}",quartzControl);
        } catch (Exception e) {
            log.error("移除任务失败",e);
        }
    }
    
}

基本的job调度类实现一个接口 QuartzJobBean

package com.techhero.common.bean.config.quartz;

import com.techhero.common.model.abs.QuartzControl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.context.ApplicationContext;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.util.StopWatch;

import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

@Slf4j
@DisallowConcurrentExecution
public class LockerQuartzJob extends QuartzJobBean {
    
    @Resource
    private ApplicationContext applicationContext;
    
    @Override
    protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
        JobDataMap    jobDataMap    = context.getJobDetail().getJobDataMap();
        QuartzControl quartzControl = (QuartzControl) jobDataMap.get("quartzControl");
        
        /*任务名称*/
        String name = quartzControl.getJobName();
        
        /*任务描述*/
        String description = quartzControl.getJobDesc();
        log.info("\n===={}任务执行===", name);
        log.info("\n任务描述:{}", description);
        
        /*时间记录*/
        StopWatch stopWatch = new StopWatch();
        stopWatch.start(name);
        
        /*服务名称*/
        String jobServiceName = quartzControl.getJobServiceName();
        if(StringUtils.isNotEmpty(jobServiceName)){
            jobServiceName=jobServiceName.trim();
            if(!Character.isLowerCase(jobServiceName.charAt(0))){
                jobServiceName=(new StringBuilder()).append(Character.toLowerCase(jobServiceName.charAt(0))).append(jobServiceName.substring(1)).toString();
            }
        }
        
        /*函数名称*/
        String jobMethodName = quartzControl.getJobMethodName();
        
        Object runBean = applicationContext.getBean(jobServiceName);
        if (runBean == null) {
            log.error("定时任务定义失败,没有这个对象实例在容器中,[{}]", jobServiceName);
            return;
        }
        
        try {
            Method runMethod = runBean.getClass().getDeclaredMethod(jobMethodName, QuartzControl.class);
            /*如果传递参数函数没有找到就查询没有参数的函数*/
            if (runMethod == null) {
                /*验证原生态函数名称*/
                runMethod = runBean.getClass().getDeclaredMethod(jobMethodName);
            }
    
            if(runMethod == null){
                /*如果原生态函数名称没有找到-就加入尾缀Impl试试带参数函数*/
                runMethod = runBean.getClass().getDeclaredMethod(jobMethodName+"Impl", QuartzControl.class);
            }
    
            if(runMethod == null){
                /*如果原生态函数名称没有找到-就加入尾缀Impl试试*/
                runMethod = runBean.getClass().getDeclaredMethod(jobMethodName+"Impl");
            }
            
            /*必须是公共函数*/
            if (runMethod != null && Modifier.isPublic(runMethod.getModifiers())) {
                runMethod.invoke(runBean, quartzControl);
                stopWatch.stop();
                log.info("定时任务执行完毕,消耗时间[ {} ]秒.", stopWatch.getTotalTimeSeconds());
            } else {
                stopWatch.stop();
                log.info("定时任务执行完毕,但任务没有执行,因为当前函数不是公用函数,消耗时间[ {} ]秒.", stopWatch.getTotalTimeSeconds());
            }
            
        } catch (Exception e) {
            log.error("[调用定时函数失败,运行异常]", e);
        }
        
    }
}

ok到这里就结束了
最后只需要写一个这样的业务类就可以调度了

package com.techhero.base.transdata.service;

import com.techhero.common.model.abs.QuartzControl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.Date;

@Service
@Slf4j
public class JobService {
    
    public void exeIntervalTime(QuartzControl quartzControl) {
        log.info("{},测试时间间隔任务.....",new Date().toLocaleString());
    }
    
    public void exeOnce(QuartzControl quartzControl) {
        log.info("{},测试只执行一次任务.....",new Date().toLocaleString());
    }
    
    public void exeCron(QuartzControl quartzControl) {
        log.info("{},测试只执行一次任务.....",new Date().toLocaleString());
    }
    
}


最后在子系统配置文件中加入这个配置就行
task:
switch: true

最后数据库脚本
oracle版本

DELETE FROM QRTZ_FIRED_TRIGGERS;
DELETE FROM QRTZ_SIMPLE_TRIGGERS;
DELETE FROM QRTZ_SIMPROP_TRIGGERS;
DELETE FROM QRTZ_CRON_TRIGGERS;
DELETE FROM QRTZ_BLOB_TRIGGERS;
DELETE FROM QRTZ_TRIGGERS;
DELETE FROM QRTZ_JOB_DETAILS;
DELETE FROM QRTZ_CALENDARS;
DELETE FROM QRTZ_PAUSED_TRIGGER_GRPS;
DELETE FROM QRTZ_LOCKS;
DELETE FROM QRTZ_SCHEDULER_STATE;

DROP TABLE QRTZ_CALENDARS;
DROP TABLE QRTZ_FIRED_TRIGGERS;
DROP TABLE QRTZ_BLOB_TRIGGERS;
DROP TABLE QRTZ_CRON_TRIGGERS;
DROP TABLE QRTZ_SIMPLE_TRIGGERS;
DROP TABLE QRTZ_SIMPROP_TRIGGERS;
DROP TABLE QRTZ_TRIGGERS;
DROP TABLE QRTZ_JOB_DETAILS;
DROP TABLE QRTZ_PAUSED_TRIGGER_GRPS;
DROP TABLE QRTZ_LOCKS;
DROP TABLE QRTZ_SCHEDULER_STATE;


CREATE TABLE QRTZ_JOB_DETAILS
  (
    SCHED_NAME VARCHAR2(120) NOT NULL,
    JOB_NAME  VARCHAR2(200) NOT NULL,
    JOB_GROUP VARCHAR2(200) NOT NULL,
    DESCRIPTION VARCHAR2(250) NULL,
    JOB_CLASS_NAME   VARCHAR2(250) NOT NULL, 
    IS_DURABLE VARCHAR2(1) NOT NULL,
    IS_NONCONCURRENT VARCHAR2(1) NOT NULL,
    IS_UPDATE_DATA VARCHAR2(1) NOT NULL,
    REQUESTS_RECOVERY VARCHAR2(1) NOT NULL,
    JOB_DATA BLOB NULL,
    CONSTRAINT QRTZ_JOB_DETAILS_PK PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
);
CREATE TABLE QRTZ_TRIGGERS
  (
    SCHED_NAME VARCHAR2(120) NOT NULL,
    TRIGGER_NAME VARCHAR2(200) NOT NULL,
    TRIGGER_GROUP VARCHAR2(200) NOT NULL,
    JOB_NAME  VARCHAR2(200) NOT NULL, 
    JOB_GROUP VARCHAR2(200) NOT NULL,
    DESCRIPTION VARCHAR2(250) NULL,
    NEXT_FIRE_TIME NUMBER(13) NULL,
    PREV_FIRE_TIME NUMBER(13) NULL,
    PRIORITY NUMBER(13) NULL,
    TRIGGER_STATE VARCHAR2(16) NOT NULL,
    TRIGGER_TYPE VARCHAR2(8) NOT NULL,
    START_TIME NUMBER(13) NOT NULL,
    END_TIME NUMBER(13) NULL,
    CALENDAR_NAME VARCHAR2(200) NULL,
    MISFIRE_INSTR NUMBER(2) NULL,
    JOB_DATA BLOB NULL,
    CONSTRAINT QRTZ_TRIGGERS_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
    CONSTRAINT QRTZ_TRIGGER_TO_JOBS_FK 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 VARCHAR2(120) NOT NULL,
    TRIGGER_NAME VARCHAR2(200) NOT NULL,
    TRIGGER_GROUP VARCHAR2(200) NOT NULL,
    REPEAT_COUNT NUMBER(7) NOT NULL,
    REPEAT_INTERVAL NUMBER(12) NOT NULL,
    TIMES_TRIGGERED NUMBER(10) NOT NULL,
    CONSTRAINT QRTZ_SIMPLE_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
    CONSTRAINT QRTZ_SIMPLE_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 
	REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);
CREATE TABLE QRTZ_CRON_TRIGGERS
  (
    SCHED_NAME VARCHAR2(120) NOT NULL,
    TRIGGER_NAME VARCHAR2(200) NOT NULL,
    TRIGGER_GROUP VARCHAR2(200) NOT NULL,
    CRON_EXPRESSION VARCHAR2(120) NOT NULL,
    TIME_ZONE_ID VARCHAR2(80),
    CONSTRAINT QRTZ_CRON_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
    CONSTRAINT QRTZ_CRON_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 
      REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);
CREATE TABLE QRTZ_SIMPROP_TRIGGERS
  (          
    SCHED_NAME VARCHAR2(120) NOT NULL,
    TRIGGER_NAME VARCHAR2(200) NOT NULL,
    TRIGGER_GROUP VARCHAR2(200) NOT NULL,
    STR_PROP_1 VARCHAR2(512) NULL,
    STR_PROP_2 VARCHAR2(512) NULL,
    STR_PROP_3 VARCHAR2(512) NULL,
    INT_PROP_1 NUMBER(10) NULL,
    INT_PROP_2 NUMBER(10) NULL,
    LONG_PROP_1 NUMBER(13) NULL,
    LONG_PROP_2 NUMBER(13) NULL,
    DEC_PROP_1 NUMERIC(13,4) NULL,
    DEC_PROP_2 NUMERIC(13,4) NULL,
    BOOL_PROP_1 VARCHAR2(1) NULL,
    BOOL_PROP_2 VARCHAR2(1) NULL,
    CONSTRAINT QRTZ_SIMPROP_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
    CONSTRAINT QRTZ_SIMPROP_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 
      REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);
CREATE TABLE QRTZ_BLOB_TRIGGERS
  (
    SCHED_NAME VARCHAR2(120) NOT NULL,
    TRIGGER_NAME VARCHAR2(200) NOT NULL,
    TRIGGER_GROUP VARCHAR2(200) NOT NULL,
    BLOB_DATA BLOB NULL,
    CONSTRAINT QRTZ_BLOB_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
    CONSTRAINT QRTZ_BLOB_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 
        REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);
CREATE TABLE QRTZ_CALENDARS
  (
    SCHED_NAME VARCHAR2(120) NOT NULL,
    CALENDAR_NAME  VARCHAR2(200) NOT NULL, 
    CALENDAR BLOB NOT NULL,
    CONSTRAINT QRTZ_CALENDARS_PK PRIMARY KEY (SCHED_NAME,CALENDAR_NAME)
);
CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS
  (
    SCHED_NAME VARCHAR2(120) NOT NULL,
    TRIGGER_GROUP  VARCHAR2(200) NOT NULL, 
    CONSTRAINT QRTZ_PAUSED_TRIG_GRPS_PK PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP)
);
CREATE TABLE QRTZ_FIRED_TRIGGERS 
  (
    SCHED_NAME VARCHAR2(120) NOT NULL,
    ENTRY_ID VARCHAR2(95) NOT NULL,
    TRIGGER_NAME VARCHAR2(200) NOT NULL,
    TRIGGER_GROUP VARCHAR2(200) NOT NULL,
    INSTANCE_NAME VARCHAR2(200) NOT NULL,
    FIRED_TIME NUMBER(13) NOT NULL,
    SCHED_TIME NUMBER(13) NOT NULL,
    PRIORITY NUMBER(13) NOT NULL,
    STATE VARCHAR2(16) NOT NULL,
    JOB_NAME VARCHAR2(200) NULL,
    JOB_GROUP VARCHAR2(200) NULL,
    IS_NONCONCURRENT VARCHAR2(1) NULL,
    REQUESTS_RECOVERY VARCHAR2(1) NULL,
    CONSTRAINT QRTZ_FIRED_TRIGGER_PK PRIMARY KEY (SCHED_NAME,ENTRY_ID)
);
CREATE TABLE QRTZ_SCHEDULER_STATE 
  (
    SCHED_NAME VARCHAR2(120) NOT NULL,
    INSTANCE_NAME VARCHAR2(200) NOT NULL,
    LAST_CHECKIN_TIME NUMBER(13) NOT NULL,
    CHECKIN_INTERVAL NUMBER(13) NOT NULL,
    CONSTRAINT QRTZ_SCHEDULER_STATE_PK PRIMARY KEY (SCHED_NAME,INSTANCE_NAME)
);
CREATE TABLE QRTZ_LOCKS
  (
    SCHED_NAME VARCHAR2(120) NOT NULL,
    LOCK_NAME  VARCHAR2(40) NOT NULL, 
    CONSTRAINT QRTZ_LOCKS_PK PRIMARY KEY (SCHED_NAME,LOCK_NAME)
);

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);



MYSQL 版本


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,
    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)
);

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)
);

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)
);

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(200) 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)
);

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)
);

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),
    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,
    CALENDAR_NAME  VARCHAR(200) NOT NULL,
    CALENDAR BLOB NOT NULL,
    PRIMARY KEY (SCHED_NAME,CALENDAR_NAME)
);

CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS
  (
    SCHED_NAME VARCHAR(120) NOT NULL,
    TRIGGER_GROUP  VARCHAR(200) NOT NULL, 
    PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP)
);

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)
);

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)
);

CREATE TABLE QRTZ_LOCKS
  (
    SCHED_NAME VARCHAR(120) NOT NULL,
    LOCK_NAME  VARCHAR(40) NOT NULL, 
    PRIMARY KEY (SCHED_NAME,LOCK_NAME)
);
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值