情景
在开发的时候可能需要用到任务调度,通常我们使用quartz,单独部署一个实例来进行任务调度,然后就会存在单点的风险,quartz帮我们实现了多台实例时候的高可用,保证同一时间只有一个任务会被执行,下面我们来看一下具体是怎么实现的。

实现原理
Quartz’s clustering features bring both high availability and scalability to your scheduler via fail-over and load balancing functionality.
Quartz 实现高可用是通过依赖JDBC-Jobstore (JobStoreTX or JobStoreCMT),来实现的,所以使用这个的前提是每个节点共享同一个数据库()
当任务触发时间开始时,每个实例上的任务会并发获取同一把锁(在后面的代码分析中我们可以看到实际上是通过数据库表的全局锁实现的),谁先获得锁谁就先执行,其它节点的任务就不会执行任务。
如果一个节点挂掉了,而且任务被标记为recovery,就会被其它节点检测到重新执行这个任务,没有被标记的话,就会再下一次任务触发的时候重新由其它节点执行。
适用情况
The clustering feature works best for scaling out long-running and/or cpu-intensive jobs (distributing the work-load over multiple nodes). If you need to scale out to support thousands of short-running (e.g 1 second) jobs, consider partitioning the set of jobs by using multiple distinct schedulers (including multiple clustered schedulers for HA). The scheduler makes use of a cluster-wide lock, a pattern that degrades performance as you add more nodes (when going beyond about three nodes - depending upon your database’s capabilities, etc.).
因为是通过加全局锁来实现的,所以比较适合 任务执行时间较长的定时任务。
使用过程
限制条件
- 集群之间的机器要保持时钟同步(大部分分布式系统都有这个要求,不必担心)
- 集群之间部分配置文件quartz.properties要保持一致,下面配置会详解
执行指定的数据库脚本
解压jar包之后,在docs/dbTables目录下,根据自己的系统适用不同的脚本,下面以mysql为例
编写相同的quartz.properties
总结
quartz的分布式任务调度可以满足大多数的开发(虽然有一些限制),如果不满足可以了解一下当当网开源的任务调度框架,贴在参考部分。
