Quartz - 任务调度框架整合使用
前言
项目中遇到一个,需要 客户自定任务启动时间 的需求。原来一直都是在项目里硬编码一些定时器,所以没有学习过。
很多开源的项目管理框架都已经做了 Quartz 的集成。我们居然连这么常用得东西居然没有做成模块化,实在是不应该。
Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,完全由Java开发,可以用来执行定时任务,类似于java.util.Timer。但是相较于Timer, Quartz增加了很多功能:
- 持久性作业 - 就是保持调度定时的状态;
- 作业管理 - 对调度作业进行有效的管理;
官方文档:Documentation (quartz-scheduler.org)、Quartz Enterprise Job Scheduler 2.3.0 API
这一篇先记一下基础使用、springboot 内的使用,以及灵活配置方式。
基础使用
Quartz 的核心类有以下三部分:
- 任务 Job :需要实现的任务类,实现
execute()
方法,执行后完成任务。 - 触发器 Trigger :包括 SimpleTrigger 和 CronTrigger。
- 调度器 Scheduler :任务调度器,负责基于 Trigger触发器,来执行 Job任务。
主要关系如下:
Demo
按照官网的 Demo,搭建一个纯 maven 项目,添加依赖:
<!-- 核心包 -->
<dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz</artifactId><version>2.3.0</version>
</dependency>
<!-- 工具包 -->
<dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz-jobs</artifactId><version>2.3.0</version>
</dependency>
新建一个任务,实现了 org.quartz.Job
接口:
public class MyJob implements Job {@Overridepublic void execute(JobExecutionContext context) throws JobExecutionException {System.out.println("任务被执行了。。。");}
}
main 方法,创建调度器、jobDetail 实例、trigger 实例、执行:
public static void main(String[] args) throws Exception {// 1.创建调度器 SchedulerSchedulerFactory factory = new StdSchedulerFactory();Scheduler scheduler = factory.getScheduler();// 2.创建JobDetail实例,并与MyJob类绑定(Job执行内容)JobDetail job = JobBuilder.newJob(MyJob.class).withIdentity("job1", "group1").build();// 3.构建Trigger实例,每隔30s执行一次Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1").startNow().withSchedule(simpleSchedule().withIntervalInSeconds(30).repeatForever()).build();// 4.执行,开启调度器scheduler.scheduleJob(job, trigger);System.out.println(System.currentTimeMillis());scheduler.start();//主线程睡眠1分钟,然后关闭调度器TimeUnit.MINUTES.sleep(1);scheduler.shutdown();System.out.println(System.currentTimeMillis());
}
日志打印情况:
JobDetail
JobDetail 的作用是绑定 Job,是一个任务实例,它为 Job 添加了许多扩展参数。
主要字段 | 涵义、作用 |
---|---|
name | 任务名称 |
group |
任务分组,默认分组 DEFAULT
|
jobClass |
任务类,就是上面 Demo 中的 MyJob 的路径
|
jobDataMap | 任务参数信息。JobDetail、Trigger 都可以使用 JobDataMap 来设置一些参数或信息。 |
每次Scheduler调度执行一个Job的时候,首先会拿到对应的Job,然后创建该Job实例,再去执行Job中的execute()的内容,任务执行结束后,关联的Job对象实例会被释放,且会被JVM GC清除。
为什么设计成JobDetail + Job,不直接使用Job?
JobDetail 定义的是任务数据,而真正的执行逻辑是在Job中。
这是因为任务是有可能并发执行,如果Scheduler直接使用Job,就会存在对同一个Job实例并发访问的问题。
而JobDetail & Job 方式,Sheduler每次执行,都会根据JobDetail创建一个新的Job实例,这样就可以 规避并发访问 的问题。
JobExecutionContext
- 当 Scheduler 调用一个 job,就会将 JobExecutionContext 传递给 Job 的 execute() 方法;
- Job 能通过 JobExecutionContext 对象访问到 Quartz 运行时候的环境以及 Job 本身的明细数据。
任务实现的 execute() 方法,可以通过 context 参数获取。
public interface Job {void execute(JobExecutionContext context)throws JobExecutionException;
}
在 Builder 建造过程中,可以使用如下方法:
usingJobData("tiggerDataMap", "测试传参")
在 execute 方法中获取:
context.getTrigger().getJobDataMap().get("tiggerDataMap");
context.getJobDetail().getJobDataMap().get("tiggerDataMap");
Job 状态参数
有状态的 job 可以理解为多次 job调用期间可以持有一些状态信息,这些状态信息存储在 JobDataMap 中。
而默认的无状态 job,每次调用时都会创建一个新的 JobDataMap。
示例如下:
//多次调用 Job 的时候,将参数保留在 JobDataMap
@PersistJobDataAfterExecution
public class JobStatus implements Job {@Overridepublic void execute(JobExecutionContext context) throws JobExecutionException {long count = (long) context.getJobDetail().getJobDataMap().get("count");System.out.println("当前执行,第" + count + "次");context.getJobDetail().getJobDataMap().put("count", ++count);}
}
JobDetail job = JobBuilder.newJob(JobStatus.class).withIdentity("statusJob", "group1").usingJobData("count", 1L).build();
输出结果:
当前执行,第1次
[main] INFO org.quartz.core.QuartzScheduler - Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED started.
当前执行,第2次
当前执行,第3次
Trigger
定时启动/关闭
Trigger 可以设置任务的开始结束时间, Scheduler 会根据参数进行触发。
Calendar instance = Calendar.getInstance();
Date startTime = instance.getTime();
instance.add(Calendar.MINUTE, 1);
Date endTime = instance.getTime();// 3.构建Trigger实例
Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1")// 开始时间.startAt(startTime)// 结束时间.endAt(endTime).build();
在 job 中也能拿到对应的时间,并进行业务判断
public void execute(JobExecutionContext context) throws JobExecutionException {System.out.println("任务执行。。。");System.out.println(context.getTrigger().getStartTime());System.out.println(context.getTrigger().getEndTime());
}
运行结果:
[main] INFO org.quartz.impl.StdSchedulerFactory - Quartz scheduler version: 2.3.0
1633149326723
任务执行。。。
Sat Oct 02 12:35:26 CST 2021
Sat Oct 02 12:36:26 CST 2021
[main] INFO org.quartz.core.QuartzScheduler - Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED started.
SimpleTrigger
这是比较简单的一类触发器,用它能实现很多基础的应用。使用它的主要场景包括:
- 在指定时间段内,执行一次任务
最基础的 Trigger 不设置循环,设置开始时间。
Quartz - 任务调度框架整合使用相关推荐
- Quartz任务调度框架
Quartz 基本概念及原理 作为一个优秀的开源调度框架,Quartz 具有以下特点: 1.强大的调度功能,例如支持丰富多样的调度方法,可以满足各种常规及特殊需求: 2. 灵活的应用方式,例如支持任务 ...
- Quartz任务调度框架之最全Quartz系统参数配置详解
我们通常是通过quartz.properties属性配置文件(默认情况下均使用该文件)结合StdSchedulerFactory 来使用Quartz的.StdSchedulerFactory 会加载属 ...
- (转)Java任务调度框架Quartz入门教程指南(四)Quartz任务调度框架之触发器精讲SimpleTrigger和CronTrigger、最详细的Cron表达式范例...
http://blog.csdn.net/zixiao217/article/details/53075009 Quartz的主要接口类是Schedule.Job.Trigger,而触发器Trigge ...
- 阿里P8架构师谈:Quartz调度框架详解、运用场景、与集群部署实践
以下将分别从Quartz架构简介.集群部署实践.Quartz监控.集群原理分析详解Quartz任务调度框架. Quartz简介 Quartz是Java领域最著名的开源任务调度工具,是一个任务调度框架, ...
- (转)Quartz任务调度(1)概念例析快速入门
http://blog.csdn.net/qwe6112071/article/details/50991563 Quartz框架需求引入 在现实开发中,我们常常会遇到需要系统在特定时刻完成特定任务的 ...
- Quartz-2.2.1 任务调度框架在Java项目中的使用实例
< Quartz-2.2.1 任务调度框架在Java项目中的使用实例 > 本实例是基于Quartz 2.2.1 版本为中心,也是目前最新的Quartz任务调度框架. 目前在 J2EE 项目 ...
- Spring整合定时任务调度框架Quartz实
Spring整合定时任务调度框架Quartz实战 定时的任务处理在程序开发中应用的相当普遍,之前一直使用JDK的Timer类库来做任务调度功能不是很方便,因为它不能像cron服务那样可以指定具体年.月 ...
- 任务调度框架Quartz用法指南(超详细)
前言 项目中遇到一个,需要 客户自定任务启动时间 的需求.原来一直都是在项目里硬编码一些定时器,所以没有学习过. 很多开源的项目管理框架都已经做了Quartz的集成.我们居然连这么常用得东西居然没有做 ...
- 任务调度框架Quartz用法指南
前言 项目中遇到一个,需要客户自定任务启动时间 的需求.以往都是在项目中直接硬编码一些定时器,趁着这次机会将quartz的相关知识记录下来. Quartz是OpenSymphony开源组织在Job s ...
最新文章
- JSP怎么将表单提交到对应的servlet
- dell系统重装后无法进入系统_笔记本电脑常见故障开机无法进入系统
- android 自定义图片上传,android自定义ImageView仿图片上传示例
- php json csv,比JSON更简单,随便记数据的CSV介绍,以及PHP解析方法-csv文件怎么打开...
- 面试必会系列 - 3.1 Redis知识点大汇总(数据类型,内存模型,持久化,缓存击穿,集群,一致性哈希等等)
- delphi 获取java控件位置_delphi的IdFTP控件函数怎么调用
- 联想e431笔记本更改硬盘模式bios设置的详细教程
- 20-10-025-安装-KyLin-2.6.0-单机版安装(MAC官网下载)成功
- 8VC Venture Cup 2016 - Final Round (Div. 2 Edition) C. XOR Equation 数学
- angular源码分析 摘抄 王大鹏 博客 directive指令及系列
- 数据库课程设计实验报告--图书馆管理系统
- 实验九 TCP 协议分析实验
- ADP-L610-Arduino
- 云服务器快速建网站_安装BT宝塔面板和wordpress
- IDEA运行web项目及乱码处理
- 标准化和归一化 超全详解
- DART Karaoke Author1.35消除原唱人声的方法制作伴奏
- 多个空格的正则表达式
- ansible角色部署mysql主从复制
- 【大讲堂】进行精细化交通设计,我们该怎么做?