Author: haoransun
Wechat: SHR—97
一、概述
Quartz是一个开放源码的任务调度框架。Quartz功能强大。可以让你的程序在指定时间执行,也可以按照某一个频度执行,支持数据库、监听器
二、环境搭建
2.1 Maven坐标
1 | <dependency> |
2.2 定义任务内容
1 |
|
2.3 构建调度任务
1 | import org.quartz.JobDetail; |
三、体系架构
- Job
是一个接口,只定义一个方法execute(JobExecutionContext context),在实现接口的execute方法中编写所需要定时执行的Job(任务),JobExecutionContext类提供了调度应用的一些信息。Job运行时的信息保存在JobDataMap实例中。 - JobDetail
JobDetail 定义的是任务数据,⽽真正的执行逻辑是在Job中。sheduler每次执⾏,都会根据JobDetail创建一个新的Job实例。 - Trigger
是一个类,描述触发Job执⾏的时间触发规则。主要有SimpleTrigger和CronTrigger这两个子类。当且仅当需调度一次或者以固定时间间隔周期执行调度,SimpleTrigger是最适合的选择;而CronTrigger则可以通过Cron表达式定义出各种复杂时间规则的调度方案:如⼯作日周一到周五的15:00~16:00执⾏调度等
Cron表达式的格式: 秒 分 时 日 月 周 年(可选)
字段名 | 允许的值 | 允许的特殊字符 |
---|---|---|
秒 | 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 | , - * / |
允许的特殊字符:
- “?”字符:表示不确定值
- “,”字符:指定数个值
- “-“字符:指定一个值的范围
- “/“字符:指定一个值得增加强度。n/m表示从n开始,每次增加m
- “L”字符:用在日表示一个月中的最后一天,用在周表示该月最后一个星期X
- “W”字符:指定离给定日期最近的工作日(周一到周五)
- “#”字符:表示该月第一个周X。6#3表示该月第三个周五
Cron表达式范例:
- 每隔5秒执行一次: */5 * * * * ?
- 每隔1分钟执行一次: 0 */1 * * * *
- 每天23点执行一次: 0 0 23 * * ?
- 每天凌晨1点执行一次: 0 0 1 * * ?
- 每月1号凌晨1点执行一次: 0 0 1 1 * ?
- 每月最后一天23点执行一次: 0 0 23 L * ?
- 每周星期天凌晨1点执行一次: 0 0 1 ? * L
- 在26分、29分、33分执行一次: 0 26,29,33 * * * ?
- 每天的0点、13点、18点、21点执行一次:0 0 0,13,18,21 * * ?
Scheduler
代表一个Quartz的独立运行容器。Trigger和JobDetail可以注册到Scheduler中,两者在Scheduler中拥有各自的组及名称,组及名称是Scheduler查找定位容器中某一对象的依据,
Trigger的组及名称必须唯一,JobDetail的组及名称也必须唯一(但可以和Trigger的组和名称相同,因为他们是不同类型的)。Scheduler定义了多个接口方法,允许外部通过组及名称访问和控制容器中Trigger和JobDetail。JobBuilder
用于定义/构建已经定义了Job实例的JobDetail实例TriggerBuilder
用于定义/构建Trigger实例。
四、Spring集成
4.1 Maven坐标
1 | <!-- quartz依赖 --> |
4.2 定义任务内容
1 | import org.quartz.Job; |
4.3 配置文件
如:Spring-quartz.xml
1 | <?xml version="1.0" encoding="UTF-8"?> |
4.4 测试
启动Spring工厂测试
1 | import org.springframework.context.support.ClassPathXmlApplicationContext; |
五、存储方式
5.1 RAMJobStore和JDBCJobStore
类型 | 优点 | 缺点 |
---|---|---|
RAMJobStore(默认) | 不要外部数据库,配置容易,运行速度快 | 因为调度程序信息是存储在被分配给JVM的内存里面,所以,当应用程序停止运行时,所有调度信息将被丢失。另外因为存储到JVM内存⾥里面,所以可以存储多少个Job和Trigger将会受到限制 |
JDBCJobStore | 支持集群,因为所有的任务信息都会保存到数据库中,可以控制事物,还有就是如果应用服务器关闭或者重启,任务信息都不会丢失,并且可以恢复因服务器关闭或者重启而导致执行失败的任务 | 运行速度的快慢取决与连接数据库的快慢 |
5.2 设置JDBCJobStore
在应用程序中设置使用JDBCJobStore需要两步:首先必须创建作业仓库使用的数据库表。JDBCJobStore 与所有主流数据库兼容。而且Quartz提供了一系列创建表的SQL脚本,能够简化设置过程。可以再Quartz发行包的“docs/dbTables”目录中找到创建的SQL脚本。第二,必须定义一些属性
- 创建Quartz数据库表
- 在quartz.properties文件中指定JDBCJobStore属性
1 | org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool |
5.3 测试
六、集群支持
6.1 原理
虽然单个Quartz实例能给予你很好的Job调度能力,但他不能满足典型的企业需求,如可伸缩性、高可靠性满足、假如你需要故障转移的能力并能运行日益增多的JOB,QUARTZ集群势必成为你应用的一部分了。使用Quartz的集群能力可以很好的支持你的业务需求,并且即使是其中一台机器在最糟的时间崩溃了也能确保所有的Job得到执行。
一个Quartz集群中的每个节点都是一个独立的Quartz应用,它又管理者其他的节点。意思是你必须对每个节点分别启动或者停止。不像许多应用服务器的集群,独立的Quartz节点并不与另一其他的节点或是管理节点通信。Quartz应用是通过数据库表来感知另一应用的。
图:表示了每个节点直接与数据库通信,若离开数据库将对其他节点一无所知
6.2 搭建步骤
- 备配置文件
- 修改 spring-quartz。xml
- 启动Spring工厂测试
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38org.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.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
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
1 | <bean id="scheduler" |