Loading...
Spring集成分布式Quartz框架之一:常规整合

Spring专题 2015/12/18 Spring Framework , Quartz

该配置为了解决WEB项目分布式部署时定时任务的并发冲突问题。

配置环境如下:

JDK 1.7

Spring 4.0.2

Quartz 2.2.1

首先要导入quartz涉及到11张表

从官网http://www.quartz-scheduler.org下载“quartz-2.2.1-distribution.tar.gz”,解压,从“quartz-2.2.1-distribution\quartz-2.2.1\docs\dbTables”目录下找到合适的您项目的脚本


两个主要配置文件:quartz.properties和applicationContext-quartz.xml,文件内容如下:

quartz.properties文件内容:

# Using Spring datasource in quartzJobsConfig.xml

# Spring uses LocalDataSourceJobStore extension of JobStoreCMT

org.quartz.jobStore.useProperties=true

org.quartz.jobStore.tablePrefix=QRTZ_

org.quartz.jobStore.isClustered=true

# 1 mins

org.quartz.jobStore.clusterCheckinInterval=15000

org.quartz.scheduler.skipUpdateCheck=true


# Change this to match your DB vendor

org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate

# Needed to manage cluster instances

org.quartz.scheduler.instanceId=AUTO

org.quartz.scheduler.instanceName=quartzInstanceName

 

org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool

org.quartz.threadPool.threadCount=10

org.quartz.threadPool.threadPriority=5

org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread=true


# Configure Plugins

org.quartz.plugin.triggHistory.class=org.quartz.plugins.history.LoggingJobHistoryPlugin

#org.quartz.plugin.triggHistory.class=org.quartz.plugins.history.LoggingTriggerHistoryPlugin

#org.quartz.plugin.triggHistory.triggerFiredMessage=Trigger \{1\}.\{0\} fired job \{6\}.\{5\} at: \{4, date, HH:mm:ss MM/dd/yyyy}

#org.quartz.plugin.triggHistory.triggerCompleteMessage=Trigger \{1\}.\{0\} completed firing job \{6\}.\{5\} at \{4, date, HH:mm:ss MM/dd/yyyy\}


applicationContext-quartz.xml文件内容:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"

xmlns:task="http://www.springframework.org/schema/task"

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-3.2.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context-3.2.xsd

http://www.springframework.org/schema/task

http://www.springframework.org/schema/task/spring-task-3.2.xsd">


<description>quartz分布式配置文件</description>


<context:annotation-config />


<!-- 任务配置 -->

<bean id="jobDetail"

class="org.springframework.scheduling.quartz.JobDetailFactoryBean">

<property name="jobClass" value="cn.imethan.admin.quartz.job.TestJob" />

<property name="durability" value="true" />

<!-- <property name="requestsRecovery" value="true" /> -->

</bean>


<!-- 触发器 -->

<bean id="jobDetailTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">

<property name="jobDetail" ref="jobDetail" />

<property name="cronExpression">

<value>0/5 * * * * ?</value>

</property>

<property name="timeZone">

<value>GMT+8:00</value>

</property>

</bean>


<!-- 任务调度配置 -->

<bean id="quartzScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">

<property name="configLocation" value="classpath:/quartz/quartz.properties" />

<property name="dataSource" ref="myDataSource" />

<property name="transactionManager" ref="myTxManager" />


<!-- This name is persisted as SCHED_NAME in db. for local testing could 

change to unique name to avoid collision with dev server -->

<property name="schedulerName" value="quartzScheduler" />


<property name="startupDelay" value="5" />


<!-- Will update database cron triggers to what is in this jobs file on 

each deploy. Replaces all previous trigger and job data that was in the database. 

YMMV -->

<property name="overwriteExistingJobs" value="true" />

<property name="autoStartup" value="true" />

<property name="applicationContextSchedulerContextKey" value="applicationContext" />

<property name="jobFactory">

<bean class="cn.imethan.admin.quartz.common.AutowiringSpringBeanJobFactory" />

</property>


<!-- NOTE: Must add both the jobDetail and trigger to the scheduler! -->

<property name="triggers">

<list>

<ref bean="jobDetailTrigger" />

</list>

</property>

<property name="jobDetails">

<list>

<ref bean="jobDetail" />

</list>

</property>

</bean>

</beans>


两个主要的类,AutowiringSpringBeanJobFactory和TestJob,类内容如下:

AutowiringSpringBeanJobFactory类内容:

package cn.imethan.admin.quartz.common;


import org.quartz.spi.TriggerFiredBundle;

import org.springframework.beans.factory.config.AutowireCapableBeanFactory;

import org.springframework.context.ApplicationContext;

import org.springframework.context.ApplicationContextAware;

import org.springframework.scheduling.quartz.SpringBeanJobFactory;


/**

 * AutowiringSpringBeanJobFactory.java

 *

 * @author Ethan Wong

 * @time 2015年9月19日下午3:33:22

 */

public final class AutowiringSpringBeanJobFactory extends SpringBeanJobFactory implements ApplicationContextAware {


private transient AutowireCapableBeanFactory beanFactory;


public void setApplicationContext(final ApplicationContext context) {

beanFactory = context.getAutowireCapableBeanFactory();

}


@Override

protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {

final Object job = super.createJobInstance(bundle);

beanFactory.autowireBean(job);

return job;

}

}


TestJob类内容如下:

package cn.imethan.admin.quartz.job;

import org.quartz.DisallowConcurrentExecution;

import org.quartz.JobExecutionContext;

import org.quartz.JobExecutionException;

import org.springframework.scheduling.quartz.QuartzJobBean;


import cn.imethan.common.utils.DateUtil;


/**

 * TestJob.java

 *

 * @author Ethan Wong

 * @time 2015年9月19日下午3:36:40

 */

@DisallowConcurrentExecution

public class TestJob extends QuartzJobBean {

    protected void executeInternal(JobExecutionContext arg0) throws JobExecutionException {

   

    System.out.println("[TestJob]Sleep 10s begin date:"+DateUtil.getDatetimeStr(DateUtil.DATE_PATTERN_01));

    try {

Thread.sleep(4000);

} catch (InterruptedException e) {

e.printStackTrace();

}

    System.out.println("[TestJob]Sleep 10s end   date:"+DateUtil.getDatetimeStr(DateUtil.DATE_PATTERN_01));

    }

    

}




参考文档

http://www.cnblogs.com/skyblue/p/3296350.html




Comments