定时任务解决方案Quartz

734 阅读4分钟

Quartz是什么呢?

www.quartz-scheduler.org/

Quartz官网是这么描述的,Quartz是一个功能丰富的开源作业调度库,可以集成到几乎任何Java应用程序中,从最小的独立应用程序到最大的电子商务系统。石英可以用来创建简单或复杂的时间表,以执行数十个、数百个甚至数万个作业;其任务被定义为标准Java组件的作业,可以执行您对其进行编程的任何操作。Quartz Scheduler包括许多企业级功能,例如支持JTA事务和集群。

对于 Quartz,可能部分程序猿小伙伴没有直接使用过,在解决定时任务场景的时候,用的最多的应该是Spring Schedule,下面简单看一下Spring Schedule 在 Spring Boot 如何使用的。

Spring Boot 使用 Schedule

spring-boot-starter已集成了springschedule 模块,无需引用额外依赖。

首先在启动类开启定时任务注解支持: @EnableScheduling

@SpringBootApplication
@EnableScheduling
public class SpringbootQuartzApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootQuartzApplication.class, args);
    }

}

简单定时任务

@Component
public class MyScheduleTask {

    // corn表达式,当方法的执行时间超过任务调度频率时,调度器会在下个周期执行
    @Scheduled(cron = "0/1 * * * * *")
    public void task(){
        System.out.println("每隔1s执行一次");
    }

    // 固定间隔,任务固定间隔时间,时间自前一次完成后计算
    @Scheduled(fixedDelay = 5000)
    public void fixedDelaySchedule() {
        System.out.println("fixedDelaySchedule");
    }

    // 固定频率,任务固定间隔时间,时间自前一次开始后计算
    @Scheduled(fixedRate = 3000)
    public void fixedRateSchedule() {
        System.out.println("fixedRateSchedule");
    }
}

Spring Scheduled 和 Quartz 有什么区别呢?

Scheduled,Spring3.0以后自带,可以将它看成一个轻量级的Quartz,而且使用起来比Quartz简单许多。默认单线程同步进行

Quartz,是一个功能比较强大的的调度器,可以让你的程序在指定时间执行,也可以按照某一个频度执行;使用起来需要继承org.springframework.scheduling.quartz.QuartzJobBean,配置稍显复杂。默认多线程异步执行,多任务之间没有直接影响。能被集群实例化,支持分布式部署

Schedule虽然开发简单,执行效率比较高,但是它只适合处理简单的计划任务,不能处理分布式计划任务,并且会出现阻塞、崩溃和延迟启动等问题。

当定时任务愈加复杂时,使用 Spring 注解 @Schedule 已经不能满足业务需要,下面看一下可应用于小到独立应用,大到电子商业系统的基于Java实现的开源的任务调度框架:Quartz

Quartz

什么是 任务调度 ?任务调度就是我们系统中创建了 个任务,每个任务都有指定的时间进行执行,而这种多任务的执行策略就是任务调度。

Quartz 的作用就是让任务调度变得更加丰富,高效,安全,而且是基于 Java 实现的,这样子开发者只需要调用几个接口坐下简单的配置,即可实现上述需求。

核心组件

Job(任务) :(what:执行什么任务)我们想要调度的任务都必须实现 org.quartz.job 接口,然后实现接口中定义的 execute( ) 方法。

Trigger(触发器) :(when:什么时间执行)作为执行任务的调度器,Trigger 又分为 SimpleTriggerCronTrigger 两种。

Scheduler(调度器) :(when to what:什么时候执行什么任务)任务的调度器,它会将任务job及触发器Trigger整合起来,负责基于Trigger设定的时间来执行Job。

Spring Boot 集成 Quartz

1、基于基础的Spring Boot工程引入maven依赖

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

2、实现Job接口并且在execute方法。

public class MyJob implements Job {
    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println(sdf.format(new Date()) + ":" + jobExecutionContext.getJobDetail().getKey() + "执行中...");
    }
}

3、创建JobDetail实例并定义Trigger注册到scheduler,启动scheduler开启调度。

@Configuration
public class QuartzSchedule {

    @Bean
     public void task() throws Exception{
        /**
         *  1、创建调度器
         *  2、创建任务对象,绑定任务类并为其命名及分组
         *  3、创建触发器,简单触发器每隔 5 秒执行一次任务
         *  4、关联任务和触发器
         *  5、启动调度器
         */
        Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();

        JobDetail jobDetail = JobBuilder.newJob(MyJob.class)
                .withIdentity("simpleJob","myJobGroup")
                .usingJobData("job_param","job_param")
                .build();

        JobDetail jobDetail2 = JobBuilder.newJob(MyJob.class)
                .withIdentity("cronJob","myJobGroup")
                .usingJobData("job_param","job_param")
                .build();

        //简单触发器
        Trigger simpleTrigger = TriggerBuilder.newTrigger()
                .withIdentity("simpleTrigger","simpleTriggerGroup")
                .startNow()
                .withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(5).repeatForever())
                .build();
        //cron触发器
        Trigger cronTrigger = TriggerBuilder.newTrigger()
                .withIdentity("cronTrigger","cronTriggerGroup")
                .startNow()
                .withSchedule(CronScheduleBuilder.cronSchedule("*/3 * * * * ?"))
                .build();

        scheduler.scheduleJob(jobDetail,simpleTrigger);

        scheduler.scheduleJob(jobDetail2,cronTrigger);

        scheduler.start();
     }
}

SimpleTrigger和CronTrigger的区别:SimpleTrigger在具体的时间点执行一次或按指定时间间隔执行多次,CronTrigger按Cron表达式的方式去执行更常用。


Cron表达式在线生成器地址:cron.qqe2.com

Gitee Demo 地址:gitee.com/renxiaoshi/…