spring-boot-route(二十一)quartz实现动态定时任务

Quartz是一个定时任务的调度框架,涉及到的主要概念有如下几个:java

Scheduler:调度器,全部的调度都由它控制,全部的任务都由它管理。mysql

Job:任务,定义业务逻辑。git

JobDetail:基于Job,进一步封装。其中关联一个Job,并为Job指定更详细的信息。github

Trigger:触发器,能够指定给某个任务,指定任务的触发机制。spring

一 建立简单任务

1.1 Quartz依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-quartz</artifactId>
</dependency>

1.2 建立任务

任务建立须要实现Job接口,重写execute(JobExecutionContext jobExecutionContext)方法,增长定时任务的业务逻辑,这里我只是简单的打印一下定时任务执行。sql

@Slf4j
public class SimpleJob implements Job {
    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        log.info("job execute---"+new Date());
    }
}

1.3 JobDetail增长属性

这里增长的属性能够在Job实现类中获取,来处理业务。数据库

JobDetail jobDetail = JobBuilder.newJob(SimpleJob.class)
                                // 任务标识,及任务分组
                                .withIdentity("job1", "group1")
                                // 连接调用,增长须要的参数
                                .usingJobData("name","Java旅途")
                                .usingJobData("age",18)
                                .build();

1.4 Trigger实现

Trigger分为两种,SimpleTriggerCronTriggerSimpleTrigger是根据Quartz的一些api实现的简单触发行为。CronTrigger用的比较多,使用cron表达式进行触发。这里先用SimpleTrigger来实现。api

SimpleTrigger simpleTrigger = TriggerBuilder.newTrigger()
                                            .withIdentity("trigger1", "group1")
                                            // 当即执行
                                            .startNow()
                                            // 10s后中止
                                            .endAt(new Date(System.currentTimeMillis()+10*1000))
                                            .withSchedule(
                                            SimpleScheduleBuilder.simpleSchedule()
                                            // 每秒执行一次
                                            .withIntervalInSeconds(1)
                                            // 一直执行
                                            .repeatForever()
                                            ).build();

1.5 启动任务

@Autowired
private Scheduler scheduler;

scheduler.scheduleJob(jobDetail,simpleTrigger);

1.6 执行效果

启动项目后,任务当即执行,每秒执行一次,10s后中止,执行效果图以下:微信

二 动态操做定时任务

有时候除了已经开发好的定时任务外,还须要咱们手动去建立任务而且控制任务的执行。app

2.1 建立任务

@GetMapping("create")
public void createJob(String jobName,String jobGroup,String cron,String triggerName,String triggerGroup) throws SchedulerException {

    JobKey jobKey = new JobKey(jobName,jobGroup);
    // 若是存在这个任务,则删除
    if(scheduler.checkExists(jobKey)) {
        scheduler.deleteJob(jobKey);
    }

    JobDetail jobDetail = JobBuilder.newJob(SimpleJob.class)
        .withIdentity(jobKey)
        .build();

    CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(cron);

    Trigger trigger = TriggerBuilder.newTrigger()
        .withIdentity(triggerName,triggerGroup)
        .withSchedule(cronScheduleBuilder).build();
    scheduler.scheduleJob(jobDetail,trigger);
}

2.2 暂停任务

@GetMapping("pause")
public void pauseJob(String jobName,String jobGroup) throws SchedulerException {

    JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
    JobDetail jobDetail = scheduler.getJobDetail(jobKey);
    if (jobDetail == null) {
        return;
    }
    scheduler.pauseJob(jobKey);
}

2.3 恢复暂停的任务

@GetMapping("remuse")
public void remuseJob(String jobName, String jobGroup) throws SchedulerException {
    JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
    JobDetail jobDetail = scheduler.getJobDetail(jobKey);
    if (jobDetail == null) {
        return;
    }
    scheduler.resumeJob(jobKey);
}

2.4 删除定时任务

@GetMapping("remove")
public void removeJob(String jobName, String jobGroup,String triggerName,String triggerGroup) throws SchedulerException {

    TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroup);
    JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
    Trigger trigger =  scheduler.getTrigger(triggerKey);
    if (trigger == null) {
        return;
    }
    // 中止触发器
    scheduler.pauseTrigger(triggerKey);
    // 移除触发器
    scheduler.unscheduleJob(triggerKey);
    // 删除任务
    scheduler.deleteJob(jobKey);
}

三 任务持久化

Quartz默认使用RAMJobStore存储方式将任务存储在内存中,除了这种方式还支持使用JDBC将任务存储在数据库,为了防止任务丢失,咱们通常会将任务存储在数据库中。

这里使用mysql进行存储,在quartz的源码包中找到文件tables_mysql_innodb.sql,而后在客户端进行运行sql文件。若是嫌源码包很差下载的话,我已经将sql文件上传至GitHub了,能够直接访问github拉去表结构,数据表以下:

3.1 增长mysql和jdbc依赖

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.11</version>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>

3.2 指定使用jdbc存储

quartz默认使用memory存储,这里修改为jdbc进行存储,并配置jdbc的相关信息

spring:
  quartz:
    job-store-type: jdbc
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/simple_fast
    username: root
    password: root

3.3 建立任务

启动项目,调用create接口建立任务,而后数据表中就会新增任务相关的数据了。

此是spring-boot-route系列的第二十一篇文章,这个系列的文章都比较简单,主要目的就是为了帮助初次接触Spring Boot 的同窗有一个系统的认识。本文已收录至个人github,欢迎各位小伙伴star

githubhttps://github.com/binzh303/s...

点关注、不迷路

若是以为文章不错,欢迎关注点赞收藏,大家的支持是我创做的动力,感谢你们。

若是文章写的有问题,请不要吝惜文笔,欢迎留言指出,我会及时核查修改。

若是你还想更加深刻的了解我,能够微信搜索「Java旅途」进行关注。回复「1024」便可得到学习视频及精美电子书。天天7:30准时推送技术文章,让你的上班路不在孤独,并且每个月还有送书活动,助你提高硬实力!