Quartz初识

一、概述
Quartz(http://www.quartz-scheduler.org/)是⼀一个开放源码的任务调度框架。Quartz功能强⼤大,
可以让你的程序在指定时间执⾏行行,也可以按照某⼀一个频度执⾏行行,⽀支持数据库、监听器器、插件、集群等
特性。
使⽤用场景:定时消息推送、定时抢购、定时发送邮件、定时统计等
二、环境搭建
Maven坐标
定义任务内容
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.2.1</version>
</dependency>
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import java.util.Date;
/**
* 任务内容
*/
public class MyJob implements Job{
public void execute(JobExecutionContext jobExecutionContext) throws
JobExecutionException {
// 输出系统当前时间
System.out.println(new Date());
构建调度任务
三、体系架构
Job
}
}
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.impl.StdSchedulerFactory;
import static org.quartz.JobBuilder.newJob;
import static org.quartz.SimpleScheduleBuilder.simpleSchedule;
import static org.quartz.TriggerBuilder.newTrigger;
/**
* 构建调度任务
*/
public class QuartzTest {
public static void main(String[] args) throws SchedulerException {
// 获取调度器器
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
// 包装任务内容
JobDetail job = newJob(MyJob.class)
.withIdentity("job1", "group1")
.build();
// 定义触发器器
Trigger trigger = newTrigger()
.withIdentity("trigger1", "group1")
.startNow()
.withSchedule(simpleSchedule()
.withIntervalInSeconds(40)
.repeatForever())
.build();
// 组装任务
scheduler.scheduleJob(job, trigger);
// 启动调度器器 开始调度
scheduler.start();
}
}
是⼀一个接⼝口,只定义⼀一个⽅方法execute(JobExecutionContext context),在实现接⼝口的execute
⽅方法中编写所需要定时执⾏行行的Job(任务), JobExecutionContext类提供了了调度应⽤用的⼀一些信息。
Job运⾏行行时的信息保存在JobDataMap实例例中。
JobDetail
JobDetail 定义的是任务数据,⽽而真正的执⾏行行逻辑是在Job中。sheduler每次执⾏行行,都会根据
JobDetail创建⼀一个新的Job实例例。
字段名 允许的值 允许的特殊字符
秒 0-59 , – * /
分 0-59 , – * /
时 0-23 , – * /
⽇日 1-31 , – * ? / L W C
⽉月 1-12 or JAN-DEC  , – * /
周 1-7 or SUN-SAT , – * ? / L C # MON FRI
年年(可选字段) empty, 1970-2099  , – * /
Trigger
是⼀一个类,描述触发Job执⾏行行的时间触发规则。主要有SimpleTrigger和CronTrigger这两个⼦子类。
当且仅当需调度⼀一次或者以固定时间间隔周期执⾏行行调度,SimpleTrigger是最适合的选择;
⽽而CronTrigger则可以通过Cron表达式定义出各种复杂时间规则的调度⽅方案:如⼯工作⽇日周⼀一到周
五的15:00~16:00执⾏行行调度等
Cron表达式的格式:秒 分 时 ⽇日 ⽉月 周 年年(可选)。
允许的特殊字符:
1. “?”字符:表示不不确定的值
2. “,”字符:指定数个值
3. “-”字符:指定⼀一个值的范围
4. “/”字符:指定⼀一个值的增加幅度。n/m表示从n开始,每次增加m
5. “L”字符:⽤用在⽇日表示⼀一个⽉月中的最后⼀一天,⽤用在周表示该⽉月最后⼀一个星期X
6. “W”字符:指定离给定⽇日期最近的⼯工作⽇日(周⼀一到周五)
7. “#”字符:表示该⽉月第⼏几个周X。6#3表示该⽉月第3个周五
Cron表达式范例例:
1. 每隔5秒执⾏行行⼀一次:*/5 * * * * ?
2. 每隔1分钟执⾏行行⼀一次:0 */1 * * * ?
3. 每天23点执⾏行行⼀一次:0 0 23 * * ?
4. 每天凌晨1点执⾏行行⼀一次:0 0 1 * * ?
5. 每⽉月1号凌晨1点执⾏行行⼀一次:0 0 1 1 * ?
6. 每⽉月最后⼀一天23点执⾏行行⼀一次:0 0 23 L * ?
7. 每周星期天凌晨1点实⾏行行⼀一次:0 0 1 ? * L
8. 在26分、29分、33分执⾏行行⼀一次:0 26,29,33 * * * ?
9. 每天的0点、13点、18点、21点都执⾏行行⼀一次:0 0 0,13,18,21 * * ?
Scheduler
代表⼀一个Quartz的独⽴立运⾏行行容器器, Trigger和JobDetail可以注册到Scheduler中, 两者在
Scheduler中拥有各⾃自的组及名称, 组及名称是Scheduler查找定位容器器中某⼀一对象的依据,
Trigger的组及名称必须唯⼀一, JobDetail的组和名称也必须唯⼀一(但可以和Trigger的组和名称相
同,因为它们是不不同类型的)。Scheduler定义了了多个接⼝口⽅方法, 允许外部通过组及名称访问和
控制容器器中Trigger和JobDetail。
JobBulider
⽤用于定义/构建已经定义了了Job实例例的JobDetail实例例
TriggerBuilder
⽤用于定义/构建Trigger实例例。
四、Spring集成
Maven坐标
<!-- quartz依赖 -->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.2.1</version>
</dependency>
<!--spring依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>3.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>3.2.8.RELEASE</version>
</dependency>
定义任务内容
配置⽂文件
如:spring-quartz.xml
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import java.util.Date;
public class MyJob implements Job{
public void execute(JobExecutionContext jobExecutionContext) throws
JobExecutionException {
System.out.println(new Date());
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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.xsd">
<!--创建JobDetail-->
<bean id="jobDetail"
class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<!--指定任务类-->
<property name="jobClass" value="MyJob"></property>
<!--当Job在没有可以使⽤用的trigger的情况下 不不删除-->
<property name="durability" value="true"></property>
</bean>
<!--注意 spring quartz整合 ⼀一个trigger只可以绑定⼀一个JobDetail ⼀一个jobDetail可
以被多个Trigger所使⽤用-->
<bean id="trigger"
class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<!--绑定JobDetail-->
<property name="jobDetail" ref="jobDetail"></property>
<property name="cronExpression" value="0-30 * * * * ?"></property>
</bean>
<bean id="trigger1"
class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<!--绑定JobDetail-->
<property name="jobDetail" ref="jobDetail"></property>
<property name="cronExpression" value="45-55 * * * * ?"></property>
测试
启动spring⼯工⼚厂测试
五、存储⽅方式
RAMJobStore和JDBCJobStore
</bean>
<!--注册trigger-->
<bean id="scheduler"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="trigger"></ref>
<ref bean="trigger1"></ref>
</list>
</property>
</bean>
</beans>
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class QuartzTest {
public static void main(String[] args) {
ClassPathXmlApplicationContext applicationContext = new
ClassPathXmlApplicationContext("spring.xml");
}
}
类型 优点 缺点
RAMJobStore(默
认)
不不要外部数据库,配置容易易,运
⾏行行速度快
因为调度程序信息是存储在被分
配给JVM的内存⾥里里⾯面,所以,当
应⽤用程序停⽌止运⾏行行时,所有调度
信息将被丢失。另外因为存储到
JVM内存⾥里里⾯面,所以可以存储多
少个Job和Trigger将会受到限制
JDBCJobStore
⽀支持集群,因为所有的任务信息
都会保存到数据库中,可以控制
事物,还有就是如果应⽤用服务器器
关闭或者重启,任务信息都不不会
丢失,并且可以恢复因服务器器关
闭或者重启⽽而导致执⾏行行失败的任

运⾏行行速度的快慢取决与连接数据
库的快慢
设置 JDBCJobStore
在应⽤用程序中设置使⽤用  JDBCJobStore 需要两步:⾸首先必须创建作业仓库使⽤用的数据库
表。 JDBCJobStore 与所有主流数据库都兼容,⽽而且 Quartz 提供了了⼀一系列列创建表的 SQL 脚本,能
够简化设置过程。可以在 Quartz 发⾏行行包的 “docs/dbTables”⽬目录中找到创建表的 SQL 脚本。第⼆二,
必须定义⼀一些属性
1. 创建Quartz数据库表
2. 在 quartz.properties⽂文件中指定 JDBCJobStore 属性
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 10
org.quartz.threadPool.threadPriority = 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread
= true
# Using RAMJobStore
## if using RAMJobStore, please be sure that you comment out the following
## - org.quartz.jobStore.tablePrefix,
## - org.quartz.jobStore.driverDelegateClass,
## - org.quartz.jobStore.dataSource
#org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
# Using JobStoreTX
## Be sure to run the appropriate script(under docs/dbTables) first to
create tables
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
# Configuring JDBCJobStore with the Table Prefix
测试
六、集群⽀支持
原理理
虽然单个Quartz实例例能给予你很好的Job调度能⼒力力,但它不不能满⾜足典型的企业需求,如可伸缩性、⾼高
可靠性满⾜足。假如你需要故障转移的能⼒力力并能运⾏行行⽇日益增多的 Job,Quartz集群势必成为你应⽤用的⼀一
部分了了。使⽤用 Quartz 的集群能⼒力力可以更更好的⽀支持你的业务需求,并且即使是其中⼀一台机器器在最糟的
时间崩溃了了也能确保所有的 Job 得到执⾏行行。
⼀一个 Quartz 集群中的每个节点是⼀一个独⽴立的 Quartz 应⽤用,它⼜又管理理着其他的节点。意思是你必须对
每个节点分别启动或停⽌止。不不像许多应⽤用服务器器的集群,独⽴立的 Quartz 节点并不不与另⼀一其的节点或
是管理理节点通信。Quartz 应⽤用是通过数据库表来感知到另⼀一应⽤用的。
图:表示了了每个节点直接与数据库通信,若离开数据库将对其他节点⼀一⽆无所知
搭建步骤
1. 准备配置⽂文件
org.quartz.jobStore.tablePrefix = QRTZ_
# Using DriverDelegate
org.quartz.jobStore.driverDelegateClass =
org.quartz.impl.jdbcjobstore.StdJDBCDelegate
# Using datasource
org.quartz.jobStore.dataSource = qzDS
# Define the datasource to use
org.quartz.dataSource.qzDS.driver = com.mysql.jdbc.Driver
org.quartz.dataSource.qzDS.URL = jdbc:mysql://localhost:3306/quartz
org.quartz.dataSource.qzDS.user = root
org.quartz.dataSource.qzDS.password = root
org.quartz.dataSource.qzDS.maxConnections = 30
2. 修改 spring-quartz.xml
org.quartz.scheduler.instanceName: TestScheduler
org.quartz.scheduler.instanceId: auto
org.quartz.scheduler.skipUpdateCheck: true
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 10
org.quartz.threadPool.threadPriority = 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThr
ead = true
# Using RAMJobStore
## if using RAMJobStore, please be sure that you comment out the
following
## - org.quartz.jobStore.tablePrefix,
## - org.quartz.jobStore.driverDelegateClass,
## - org.quartz.jobStore.dataSource
#org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
# Using JobStoreTX
## Be sure to run the appropriate script(under docs/dbTables) first to
create tables
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.isClustered = true
# Configuring JDBCJobStore with the Table Prefix
org.quartz.jobStore.tablePrefix = QRTZ_
# Using DriverDelegate
org.quartz.jobStore.driverDelegateClass =
org.quartz.impl.jdbcjobstore.StdJDBCDelegate
# Using datasource
org.quartz.jobStore.dataSource = qzDS
# Define the datasource to use
org.quartz.dataSource.qzDS.driver = com.mysql.jdbc.Driver
org.quartz.dataSource.qzDS.URL = jdbc:mysql://localhost:3306/quartz
org.quartz.dataSource.qzDS.user = root
org.quartz.dataSource.qzDS.password = root
org.quartz.dataSource.qzDS.maxConnections = 30
3. 启动spring⼯工⼚厂并测试
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值