Quartz学习总结
一、基本介绍:
Quartz 是 OpenSymphony 开源组织在任务调度领域的一个开源项目,完全基于 Java 实现。该项目于 2009 年被 Terracotta 收购,目前是 Terracotta 旗下的一个项目。读者可以到 http://www.quartz-scheduler.org/站点下载 Quartz 的发布版本及其源代码。
Quartz 具有以下特点:
1、强大的调度功能,例如支持丰富多样的调度方法,可以满足各种常规及特殊需求;
2、灵活的应用方式,例如支持任务和调度的多种组合方式,支持调度数据的多种存储方式;
3、分布式和集群能力,Terracotta 收购后在原来功能基础上作了进一步提升。
这些总结起来就是:在某一个有规律的时间点干某件事。并且时间的触发的条件可以非常复杂(比如每月最后一个工作日的17:50),复杂到需要一个专门的框架来干这个事。 Quartz就是来干这样的事,你给它一个触发条件的定义,它负责到了时间点,触发相应的Job起来干活。
二、POM引用:
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.3</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.2.3</version>
</dependency>
三、基本结构:
(一)核心元素:
1、Scheduler:一个scheduler的生命周期是有限的,从通过SchedulerFactory创建开始直到调用它的shutdown()方法。scheduler接口一旦创建,就能添加、移除、和列出job和trigger,并执行另一些与调度相关的操作(例如暂停trigger),然而,在scheduler被start()方法启动前,它不会作用于任何trigger(执行job)。。
2、Job: 一个job就是实现了Job接口的类。如下所示,这个接口只有一个简单的方法:execute;
3、JobDetail: JobDetail对象由Quartz客户端(你的程序)在job添加进scheduler的时候创建。这个对象包含了很多job的属性设置,和JobDataMap一样,它能够存储你的job实例的状态信息。JobDetail对象本质上是定义的job实例。
4、Trigger:
(1) trigger对象常常用于触发job的执行(或者触发),当你希望安排一个job,你可以实例化一个trigger,并调整其属性来提供你想要的调度。trigger可能有一个与它们关联的JobDataMap对象。JobDataMap用于传递特定于触发器触发的工作参数。Quartz附带一些不同的触发类型,但是最常用的就是SimpleTrigger和CronTrigger。
(2) SimpleTrigger很方便,如果你需要一次性执行(只是在一个给定时刻执行job),或者如果你需要一个job在一个给定的时间,并让它重复N次,并在执行之间延迟T。
(3) CronTrigger是有用的,如果你想拥有引发基于当前日历时间表,如每个星期五,中午或在每个月的第十天 10:15。
5、JobBuilder: 用于定义/构建已经定义了Job实例的JobDetail实例。
6、TriggerBuilder: 用于定义/构建Trigger实例。
(二)数据表说明:
序号 |
表名 |
说明 |
1 |
QRTZ_CALENDARS |
存储Quartz的Calendar信息 |
2 |
QRTZ_CRON_TRIGGERS |
存储CronTrigger,包括Cron表达式和时区信息 |
3 |
QRTZ_FIRED_TRIGGERS |
存储与已触发的Trigger相关的状态信息,以及相联Job的执行信息 |
4 |
QRTZ_PAUSED_TRIGGER_GRPS |
存储已暂停的Trigger组的信息 |
5 |
QRTZ_SCHEDULER_STATE |
存储少量的有关Scheduler的状态信息,和别的Scheduler实例 |
6 |
QRTZ_LOCKS |
存储程序的悲观锁的信息 |
7 |
QRTZ_JOB_DETAILS |
存储每一个已配置的Job的详细信息 |
8 |
QRTZ_SIMPLE_TRIGGERS |
存储简单的Trigger,包括重复次数、间隔、以及已触的次数 |
9 |
QRTZ_BLOG_TRIGGERS |
Trigger作为Blob类型存储 |
10 |
QRTZ_TRIGGERS |
存储已配置的Trigger的信息 |
11 |
QRTZ_SIMPROP_TRIGGERS |
(三)关系图:
Quartz 任务调度的核心元素是 scheduler, trigger 和 job,其中 trigger 和 job 是任务调度的元数据, scheduler 是实际执行调度的控制器。
在 Quartz 中,trigger 是用于定义调度时间的元素,即按照什么时间规则去执行任务。Quartz 中主要提供了四种类型的 trigger:SimpleTrigger,CronTirgger,DateIntervalTrigger,和 NthIncludedDayTrigger。这四种 trigger 可以满足企业应用中的绝大部分需求。
在 Quartz 中,job 用于表示被调度的任务。主要有两种类型的 job:无状态的(stateless)和有状态的(stateful)。对于同一个 trigger 来说,有状态的 job 不能被并行执行,只有上一次触发的任务被执行完之后,才能触发下一次执行。Job 主要有两种属性:volatility 和 durability,其中 volatility 表示任务是否被持久化到数据库存储,而 durability 表示在没有 trigger 关联的时候任务是否被保留。两者都是在值为 true 的时候任务被持久化或保留。一个 job 可以被多个 trigger 关联,但是一个 trigger 只能关联一个 job。
在 Quartz 中, scheduler 由 scheduler 工厂创建:DirectSchedulerFactory 或者 StdSchedulerFactory。 第二种工厂 StdSchedulerFactory 使用较多,因为 DirectSchedulerFactory 使用起来不够方便,需要作许多详细的手工编码设置。 Scheduler 主要有三种:RemoteMBeanScheduler, RemoteScheduler 和 StdScheduler。本文以最常用的 StdScheduler 为例讲解。这也是笔者在项目中所使用的 scheduler 类。
线程图:
Scheduler 调度线程主要有两个: 执行常规调度的线程,和执行 misfired trigger 的线程。常规调度线程轮询存储的所有 trigger,如果有需要触发的 trigger,即到达了下一次触发的时间,则从任务执行线程池获取一个空闲线程,执行与该 trigger 关联的任务。Misfire 线程是扫描所有的 trigger,查看是否有 misfired trigger,如果有的话根据 misfire 的策略分别处理。
(四)启动流程:
若quartz是配置在spring中,当服务器启动时,就会装载相关的bean。SchedulerFactoryBean实现了InitializingBean接口,因此在初始化bean的时候,会执行afterPropertiesSet方法,该方法将会调用SchedulerFactory(DirectSchedulerFactory 或者 StdSchedulerFactory,通常用StdSchedulerFactory)创建Scheduler。SchedulerFactory在创建quartzScheduler的过程中,将会读取配置参数,初始化各个组件。
四、简单示例:
public class HelloJob implements Job {
public HelloJob() {
} public void execute(JobExecutionContext context) throws JobExecutionException {
System.out.println("Hello World! - " + new Date());
}
}
public class SimpleExample {
public void run() throws Exception {
System.out.println("------- 初始化 ----------------------");
// 首先要实例化scheduler
SchedulerFactory schedulerFactory = new StdSchedulerFactory();
Scheduler scheduler = schedulerFactory.getScheduler();
System.out.println("------- 初始化完成 -----------"); // 获取给定时间的下一个完整分钟的时间,例如给定时间 08:13:54 则会反回 08:14:00
Date runTime = DateBuilder.evenMinuteDate(new Date()); System.out.println("------- Job安排 -------------------");
// 获取job实例
JobDetail job = JobBuilder.newJob(HelloJob.class).withIdentity("job1", "group1").build();
// 在下一轮分钟触发运行
Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1").startAt(runTime).build();
// 告诉quartz使用某个trigger执行某个job
scheduler.scheduleJob(job, trigger);
System.out.println(job.getKey() + " 将会运行于: " + runTime); // 启动scheduler
scheduler.start(); System.out.println("------- 开始安排 -----------------");
System.out.println("------- 等待65秒 -------------");
Thread.sleep(65L * 1000L); // 关闭scheduler
System.out.println("------- 关闭 ---------------------");
scheduler.shutdown(true);
System.out.println("------- 关闭完成 -----------------");
} public static void main(String[] args) throws Exception {
SimpleExample example = new SimpleExample();
example.run();
}
}
五、Spring集成:
1、新建spring工程以及maven引入quartz包;
2、application.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd"> <!--
Spring整合Quartz进行配置遵循下面的步骤:
1:定义工作任务的Job
2:定义触发器Trigger,并将触发器与工作任务绑定
3:定义调度器,并将Trigger注册到Scheduler
-->
<!-- 1:定义任务的bean ,这里使用JobDetailFactoryBean,也可以使用MethodInvokingJobDetailFactoryBean ,配置类似-->
<bean name="hwJob" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<!-- 指定job的名称 -->
<property name="name" value="hw_job"/>
<!-- 指定job的分组 -->
<property name="group" value="hw_group"/>
<!-- 指定具体的job类 -->
<property name="jobClass" value="com.dufy.spring.quartz.chapter01.job.HelloWorldJob"/>
<!-- 必须设置为true,如果为false,当没有活动的触发器与之关联时会在调度器中会删除该任务 -->
<property name="durability" value="true"/>
<!-- 指定spring容器的key,如果不设定在job中的jobmap中是获取不到spring容器的 -->
<property name="applicationContextJobDataKey" value="applicationContext"/>
</bean>
<!-- 2.1:定义触发器的bean,定义一个Simple的Trigger,一个触发器只能和一个任务进行绑定 -->
<!-- <bean name="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
指定Trigger的名称
<property name="name" value="hw_trigger"/>
指定Trigger的名称
<property name="group" value="hw_trigger_group"/>
指定Tirgger绑定的Job
<property name="jobDetail" ref="hwJob"/>
指定Trigger的延迟时间 1s后运行
<property name="startDelay" value="1000"/>
指定Trigger的重复间隔 5s
<property name="repeatInterval" value="5000"/>
指定Trigger的重复次数
<property name="repeatCount" value="5"/>
</bean> -->
<!-- 2.2:定义触发器的bean,定义一个Cron的Trigger,一个触发器只能和一个任务进行绑定 -->
<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<!-- 指定Trigger的名称 -->
<property name="name" value="hw_trigger"/>
<!-- 指定Trigger的名称 -->
<property name="group" value="hw_trigger_group"/>
<!-- 指定Tirgger绑定的Job -->
<property name="jobDetail" ref="hwJob"/>
<!-- 指定Cron 的表达式 ,当前是每隔1s运行一次 -->
<property name="cronExpression" value="0/1 * * * * ?" />
</bean>
<!-- 3.定义调度器,并将Trigger注册到调度器中 -->
<bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<!-- <ref bean="simpleTrigger"/> -->
<ref bean="cronTrigger"/>
</list>
</property>
<!-- <property name="autoStartup" value="true" /> -->
</bean>
<!-- 持久化数据配置,需要添加quartz.properties-->
<bean name="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="applicationContextSchedulerContextKey" value="applicationContextKey"/>
<property name="configLocation" value="classpath:quartz.properties"/>
</bean>
</beans>
3、quartz.properties:
org.quartz.scheduler.instanceName: dufy_test
org.quartz.scheduler.instanceId = AUTO org.quartz.scheduler.rmi.export: false
org.quartz.scheduler.rmi.proxy: false
org.quartz.scheduler.wrapJobExecutionInUserTransaction: false
#============================================================================
# Configure ThreadPool
#============================================================================
org.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount: 2
org.quartz.threadPool.threadPriority: 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread: true org.quartz.jobStore.misfireThreshold: 60000
#============================================================================
# Configure JobStore
#============================================================================ #default config
#org.quartz.jobStore.class: org.quartz.simpl.RAMJobStore
#持久化配置
org.quartz.jobStore.class:org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass:org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.useProperties:true #============================================================================
#havent cluster spring
#============================================================================
org.quartz.jobStore.isClustered = false #数据库表前缀
org.quartz.jobStore.tablePrefix:qrtz_
org.quartz.jobStore.dataSource:qzDS #============================================================================
# Configure Datasources
#============================================================================
#JDBC驱动
org.quartz.dataSource.qzDS.driver:com.mysql.jdbc.Driver
org.quartz.dataSource.qzDS.URL:jdbc:mysql://localhost:3306/quartz_test
org.quartz.dataSource.qzDS.user:root
org.quartz.dataSource.qzDS.password:root
org.quartz.dataSource.qzDS.maxConnection:10
4、Job类的实现:
public class HelloWorldJob implements Job{ private Logger log = LoggerFactory.getLogger(this.getClass()); public void execute(JobExecutionContext arg0) throws JobExecutionException {
log.info("This is a first spring combine quartz !");
log.info("Welcome to Spring_Quartz World!"+ new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) );
log.info("Let's begin ! \n \n");
}
}
5、调度程序的实现:
public class HWTest {
private static Scheduler scheduler; public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("spring_quartz.xml");
scheduler = (StdScheduler)ac.getBean("scheduler");
startSchedule();
} public static void startSchedule() {
try {
// 1、创建一个JobDetail实例,指定Quartz
JobDetail jobDetail = JobBuilder.newJob(HelloWorldJob.class)
.withIdentity("job1_1", "jGroup1")
// 任务名,任务组
.build();
// 触发器类型
//SimpleScheduleBuilder builder = SimpleScheduleBuilder
// 设置执行次数
//.repeatSecondlyForTotalCount(5);
CronScheduleBuilder builder = CronScheduleBuilder.cronSchedule("0/2 * * * * ?");
// 2、创建Trigger
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("trigger1_1", "tGroup1").startNow()
.withSchedule(builder)
.build();
// 3、创建Scheduler
scheduler = StdSchedulerFactory.getDefaultScheduler();
scheduler.start();
// 4、调度执行
scheduler.scheduleJob(jobDetail, trigger);
} catch (SchedulerException e) {
e.printStackTrace();
}
}
}
六、参考资料:
https://www.cnblogs.com/drift-ice/p/3817269.html
https://blog.csdn.net/lkl_csdn/article/details/73613033
https://blog.csdn.net/u010648555/article/details/53363321
https://blog.csdn.net/gjb724332682/article/details/53019953?utm_source=blogkpcl6
Quartz学习总结的更多相关文章
- Quartz学习——Spring和Quartz集成详解(三)
Spring是一个很优秀的框架,它无缝的集成了Quartz,简单方便的让企业级应用更好的使用Quartz进行任务的调度.下面就对Spring集成Quartz进行简单的介绍和示例讲解!和上一节 Quar ...
- Quartz学习-- quartz基本介绍和 Cron表达式
Quartz学习 一. Quartz 大致简介 Quartz 是完全由 java 开发的一个开源的任务日程管理系统 任务日程管理系统 换句话说就是: 一个预先确定的日程时间到达时,负责执行任务的 ...
- Quartz学习--二 Hello Quartz! 和源码分析
Quartz学习--二 Hello Quartz! 和源码分析 三. Hello Quartz! 我会跟着 第一章 6.2 的图来 进行同步代码编写 简单入门示例: 创建一个新的java普通工程 ...
- Quartz学习——SSMM(Spring+SpringMVC+Mybatis+Mysql)和Quartz集成详解(转)
通过前面的学习,你可能大致了解了Quartz,本篇博文为你打开学习SSMM+Quartz的旅程!欢迎上车,开始美好的旅程! 本篇是在SSM框架基础上进行的. 参考文章: 1.Quartz学习——Qua ...
- Java任务调度开源框架quartz学习
一.quartz学习 Java框架介绍:Quartz从入门到进阶 http://edu.yesky.com/edupxpt/233/2209233.shtml 1.例子:http://javacraz ...
- Quartz学习笔记:集群部署&高可用
Quartz学习笔记:集群部署&高可用 集群部署 一个Quartz集群中的每个节点是一个独立的Quartz应用,它又管理着其他的节点.这就意味着你必须对每个节点分别启动或停止.Quartz集群 ...
- Quartz学习笔记:基础知识
Quartz学习笔记:基础知识 引入Quartz 关于任务调度 关于任务调度,Java.util.Timer是最简单的一种实现任务调度的方法,简单的使用如下: import java.util.Tim ...
- Quartz 学习记录1
原因 公司有一些批量定时任务可能需要在夜间执行,用的是quartz和spring batch两个框架.quartz是个定时任务框架,spring batch是个批处理框架. 虽然我自己的小玩意儿平时不 ...
- Quartz学习——SSMM(Spring+SpringMVC+Mybatis+Mysql)和Quartz集成详解(四)
当任何时候觉你得难受了,其实你的大脑是在进化,当任何时候你觉得轻松,其实都在使用以前的坏习惯. 通过前面的学习,你可能大致了解了Quartz,本篇博文为你打开学习SSMM+Quartz的旅程!欢迎上车 ...
- (转) Quartz学习——SSMM(Spring+SpringMVC+Mybatis+Mysql)和Quartz集成详解(四)
http://blog.csdn.net/u010648555/article/details/60767633 当任何时候觉你得难受了,其实你的大脑是在进化,当任何时候你觉得轻松,其实都在使用以前的 ...
随机推荐
- DevExpress Windows 10 UWP Controls新版亮点
行业领先的.NET界面控件2018年第二次重大更新——DevExpress v18.2日前正式发布,本站将以连载的形式为大家介绍新版本新功能.本文将介绍了DevExpress Windows 10 U ...
- 使用MyEclipse开发Java EE应用:用XDoclet创建EJB 2 Session Bean项目(一)
[MyEclipse最新版下载] 一.创建一个EJB项目 1. 选择File>New Project,选择EJB Project,然后单击Next. 2. 在Project name字段中输入f ...
- http协议相关
HTTP请求方法 HTTP消息头 HTTP请求头 HTTP响应头 HTTP cookie机制和实现原理 HTTP请求方法 超文本传输协议(HTTP, HyperText Transfer Protoc ...
- connection reset 分析解决(转载)
文章转自:https://my.oschina.net/xionghui/blog/508758;记录下来以便以后复习查阅; 在使用HttpClient调用后台resetful服务时,“Connect ...
- 记一次ios加急上架经历
https://developer.apple.com//contact/app-store/?topic=expedite app迭代版本上架之前一直好好的没报错,没crash,但是有一次加急上架, ...
- 3--Selenium环境准备--Eclipse 引入 selenium-server包
1.下载selenium-server包 selenium-server-standalone包是Seleniumd的核心jar包,其中包含了各种元素定位和调用浏览器的方法.下载jar包后,在ID ...
- FZU 2273 Triangles 第八届福建省赛 (三角形面积交 有重边算相交)
Problem Description This is a simple problem. Given two triangles A and B, you should determine they ...
- SQL注入之Sqli-labs系列第二关
废话不在多说 let's go! 继续挑战第二关(Error Based- Intiger) 同样的前奏,就不截图了 ,and 1=1和and 1=2进行测试,出现报错 还原sql语句 查看源代 ...
- react-native-echarts 解决数据刷新闪烁,不能动态连续绘制问题(转载)
最终能实现效果:动态绘制K线图,安卓,iOS正常显示 替换node_modules/native-echarts/src/components/Echarts/中的index.js和renderCha ...
- apache ab 压力测试
我今天在慕课网中无意之间看到压力测试,可以模拟高并发; 顺便看了一下有没有相关的博客,发现下面的这个很详细; //在apache 安装目录下的bin,运行命令 ab -n1000 -c10 http: ...