Quartz的集群

发表时间:2018-01-16 19:54:04 浏览量( 23 ) 留言数( 0 )

学习目标:

1、了解Quartz的集群的原理

2、掌握Quartz的集群的配置


学习过程:

一、介绍   

集群通过故障切换和负载平衡的功能,能给调度器带来高可用性和伸缩性。目前集群只能工作在JDBC-JobStore(JobStore TX或者JobStoreCMT)方式下,从本质上来说,是使集群上的每一个节点通过共享同一个数据库来工作的(Quartz通过启动两个维护线程来维护数据库状态实现集群管理,一个是检测节点状态线程,一个是恢复任务线程)。

   负载平衡是自动完成的,集群的每个节点会尽快触发任务。当一个触发器的触发时间到达时,第一个节点将会获得任务(通过锁定),成为执行任务的节点。

   故障切换的发生是在当一个节点正在执行一个或者多个任务失败的时候。当一个节点失败了,其他的节点会检测到并且标 识在失败节点上正在进行的数据库中的任务。任何被标记为可恢复(任务详细信息的"requests recovery"属性)的任务都会被其他的节点重新执行。没有标记可恢复的任务只会被释放出来,将会在下次相关触发器触发时执行。

二、集群配置

     通过设置"org.quartz.jobStore.isClustered"属性为"true"来激活集群特性。在集群中的每一个实例都必须有一 个唯一的"instance id" ("org.quartz.scheduler.instanceId" 属性), 但是应该有相同的"scheduler instance name" ("org.quartz.scheduler.instanceName"),也就是说集群中的每一个实例都必须使用相同的 quartz.properties 配置文件。除了以下几种例外,配置文件的内容其他都必须相同:

 不同的线程池大小,

 不同的"org.quartz.scheduler.instanceId"属性值(这个可以很容易做到,设定为"AUTO"即可)。


三、代码

如果你有两台电脑,那么就可以设置org.quartz.scheduler.instanceId为auto即可。然后再两台电脑运行,这里我只在自己的电脑上面测试。

配置:

# Cluster

org.quartz.jobStore.isClustered=true  

org.quartz.jobStore.acquireTriggersWithinLock=true  

org.quartz.jobStore.clusterCheckinInterval = 3000 

org.quartz.scheduler.instanceId=liubao

启动代码,注意Job 设置requestRecovery()

public class QuartzTest {

	public static void main(String[] args) {

		try {
			SchedulerFactory schedFact = new org.quartz.impl.StdSchedulerFactory();

			Scheduler sched = schedFact.getScheduler();

			sched.start();

			// define the job and tie it to our HelloJob class
			JobDetail job = newJob(HelloJob.class).withIdentity("myJob", "group1").storeDurably().requestRecovery().build();

			Trigger trigger = newTrigger().withIdentity("myTrigger22", "group22").startNow()
					.withSchedule(simpleSchedule().withIntervalInSeconds(3).repeatForever()).build();

			// Tell quartz to schedule the job using our trigger
			sched.scheduleJob(job,trigger);

		} catch (SchedulerException se) {
			se.printStackTrace();
		}
	}
}


然后我们修改配置文件的

org.quartz.scheduler.instanceId=other


启动文件可以删除Job和Trigger

public class QuartzTest {

	public static void main(String[] args) {

		try {
			SchedulerFactory schedFact = new org.quartz.impl.StdSchedulerFactory();

			Scheduler sched = schedFact.getScheduler();

			sched.start();


		} catch (SchedulerException se) {
			se.printStackTrace();
		}
	}
}


   你可以继续修改org.quartz.scheduler.instanceId=other的值,继续启动多一个实例,你会发现任务只在一台上面运行,可以很好的做到负载均衡;然后尝试停了正在运行的哪一个。你会发现启动的实例过一段时间后会继续运行,这就是故障切换。