Quartz集群配备

Quartz集群配置

本文基于spring3.2+quartz1.8.6配置,参考了网上的实现。


1、创建mysql数据库,执行quartz-1.8.6\docs\dbTables\tables_mysql.sql

 

2、新建quartz.properties来覆盖jar包中的此文件。

#==============================================================  
#Configure Main Scheduler Properties  
#==============================================================   
org.quartz.scheduler.instanceName = quartzScheduler
org.quartz.scheduler.instanceId = AUTO

#==============================================================  
#Configure JobStore  
#============================================================== 
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.jobStore.isClustered = true
org.quartz.jobStore.clusterCheckinInterval = 20000  
org.quartz.jobStore.dataSource = myDS
 
#==============================================================  
#Configure DataSource
#============================================================== 
org.quartz.dataSource.myDS.driver = com.mysql.jdbc.Driver
org.quartz.dataSource.myDS.URL = jdbc:mysql://10.4.247.100:3306/quartz?useUnicode=true&characterEncoding=UTF-8
org.quartz.dataSource.myDS.user = root
org.quartz.dataSource.myDS.password = 123456
org.quartz.dataSource.myDS.maxConnections = 30

#==============================================================  
#Configure ThreadPool  
#============================================================== 
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 10
org.quartz.threadPool.threadPriority = 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true

 

3、MethodInvokingJobDetailFactoryBean 类中的 methodInvoking 方法,是不支持序列化的,因此在把 QUARTZ 的 TASK 序列化进入数据库时就会抛错。需要自己实现MethodInvokingJobDetailFactoryBean 的功能,这里用MyDetailQuartzJobBean 替换。

public class MyDetailQuartzJobBean extends QuartzJobBean {
	
	protected final Log log = LogFactory.getLog(getClass());
	private String targetObject;
	private String targetMethod;
	private ApplicationContext ctx;

	@Override
	protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
		try {
			//log.info("execute [" + targetObject + "] at once>>>>>>");
			Object otargetObject = ctx.getBean(targetObject);
			Method m = null;

			try {
				m = otargetObject.getClass().getMethod(targetMethod, new Class[] {JobExecutionContext.class});
				m.invoke(otargetObject, new Object[] {context});
			} catch (SecurityException e) {
				log.error(e);
			} catch (NoSuchMethodException e) {
				log.error(e);
			}
		} catch (Exception e) {
			throw new JobExecutionException(e);
		}
	}

	public void setApplicationContext(ApplicationContext applicationContext) {
		this.ctx = applicationContext;
	}

	public void setTargetObject(String targetObject) {
		this.targetObject = targetObject;
	}

	public void setTargetMethod(String targetMethod) {
		this.targetMethod = targetMethod;
	}
}

 4、编写业务调用类

public class FirstJob implements Job {

	private final Log log = LogFactory.getLog(this.getClass());
	
	@Override
	public void execute(JobExecutionContext arg0) throws JobExecutionException {
		
		log.info(this.getClass().getName() + "-->" + new Timestamp(System.currentTimeMillis()));
	}

}

public class SecondJob implements Job {

	private final Log log = LogFactory.getLog(this.getClass());
	
	@Override
	public void execute(JobExecutionContext arg0) throws JobExecutionException {		
		log.info(this.getClass().getName() + "-->" + new Timestamp(System.currentTimeMillis()));
	}

}

 5、spring配置文件

	<!-- 1、配置文件中添加业务类,该类为调用的工作类  --> 
	<bean id="firstJob" class="cn.sh.ideal.quartz.FirstJob" />	
	<bean id="secondJob" class="cn.sh.ideal.quartz.SecondJob" />
	  

	<!-- 2、定义任务,在spring文件中配置代理类 ,定义调用对象和调用对象的方法-->
	<bean id="firstTask" class="org.springframework.scheduling.quartz.JobDetailBean">
		<property name="jobClass">
			<value>cn.sh.ideal.quartz.MyDetailQuartzJobBean</value>
		</property>
		<property name="jobDataAsMap">
			<map>
				<entry key="targetObject" value="firstJob" />
				<entry key="targetMethod" value="execute" />
			</map>
		</property>
	</bean>

	<bean id="secondTask" class="org.springframework.scheduling.quartz.JobDetailBean">
		<property name="jobClass">
			<value>cn.sh.ideal.quartz.MyDetailQuartzJobBean</value>
		</property>
		<property name="jobDataAsMap">
			<map>
				<entry key="targetObject" value="secondJob" />
				<entry key="targetMethod" value="execute" />
			</map>
		</property>
	</bean>

	<!-- 3、配置触发器,定义触发时间,可以根据不同的时间对同一个任务定义多个触发器,下面是每隔10秒调用一个方法配置-->  
	<!-- cron表达式   -->
	<bean id="firstCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">  
		<property name="jobDetail" ref="firstTask"/>  
		<property name="cronExpression" value="10,20,30,40,50 * * * * ?"/>  
	</bean>
	<bean id="secondCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">  
		<property name="jobDetail" ref="secondTask"/>  
		<property name="cronExpression" value="5,15,25,35,45,55 * * * * ?"/>  
	</bean> 
	
	<!-- 4、配置调度器 ,容器启动就会执行调度程序  -->  
	<!-- 总管理类,如果lazy-init='false',则容器启动时就会执行调度程序-->    
	<!-- 如果lazy-init='true',则需要实例化该bean才能执行调度程序            -->    
	<bean id="schdulerFactory" lazy-init="true" autowire="no" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">  
		<property name="triggers">  
			<list>				
				<ref bean="firstCronTrigger"/>
				<ref bean="secondCronTrigger"/>
			</list>  
		</property>
		<property name="applicationContextSchedulerContextKey" value="applicationContext" />
		<property name="configLocation" value="classpath:quartz.properties" />  
	</bean>

 


参考文档

1、Quartz集群配置 http://forhope.iteye.com/blog/1398990

2、quartz在集群环境下的最终解决方案 http://blog.****.net/lifetragedy/article/details/6212831

3、spring结合quartz的执行多任务的实现 http://rongdmmap-126-com.iteye.com/blog/1434378

4、cronmaker http://www.cronmaker.com/