Quartz是什么呢?
Quartz官网是这么描述的,Quartz是一个功能丰富的开源作业调度库,可以集成到几乎任何Java应用程序中,从最小的独立应用程序到最大的电子商务系统。石英可以用来创建简单或复杂的时间表,以执行数十个、数百个甚至数万个作业;其任务被定义为标准Java组件的作业,可以执行您对其进行编程的任何操作。Quartz Scheduler包括许多企业级功能,例如支持JTA事务和集群。
对于 Quartz,可能部分程序猿小伙伴没有直接使用过,在解决定时任务场景的时候,用的最多的应该是Spring Schedule,下面简单看一下Spring Schedule 在 Spring Boot 如何使用的。
Spring Boot 使用 Schedule
spring-boot-starter已集成了spring 的 schedule 模块,无需引用额外依赖。
首先在启动类开启定时任务注解支持: @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 又分为 SimpleTrigger 和 CronTrigger 两种。
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/…