springmvc+quartz集群(cluster)配置

在测试和生产环境一般服务器的部署不会少于2台。这时定时任务的配置问题尤其重要,因为定时任务只需要跑一次。

有的公司采用的做法是,单独一台服务器部署跑批服务,其他服务器提供其他业务服务。另外的一种做法是使用quartz集群。

本文将介绍spring mvc框架中quartz集群的搭建方法。

maven项目中增加quartz依赖,

<dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz</artifactId>
    <version>2.2.1</version>
</dependency>
<dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz-jobs</artifactId>
    <version>2.2.1</version>
</dependency> 

在src目录下(maven项目在src/main/resources下)增加quartz.properties(必须是这个名字)文件,文件内容如下:

#==============================================================

#Configure Main Scheduler Properties

#==============================================================
org.quartz.scheduler.instanceName = clusterScheduler
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
org.quartz.jobStore.maxMisfiresToHandleAtATime = 1
org.quartz.jobStore.misfireThreshold = 120000
org.quartz.jobStore.txIsolationLevelSerializable = true

#==============================================================

#Configure DataSource

#==============================================================

#org.quartz.dataSource.myDS.driver = com.mysql.jdbc.Driver

#org.quartz.dataSource.myDS.URL = jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=UTF-8

#org.quartz.dataSource.myDS.user = root

#org.quartz.dataSource.myDS.password = root

#org.quartz.dataSource.myDS.maxConnections = 30
org.quartz.jobStore.selectWithLockSQL = SELECT * FROM {0}LOCKS WHERE LOCK_NAME = ? FOR UPDATE

#==============================================================

#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

#==============================================================

#Skip Check Update

#update:true

#not update:false

#==============================================================
org.quartz.scheduler.skipUpdateCheck = true

#============================================================================

Configure Plugins

#============================================================================
org.quartz.plugin.triggHistory.class = org.quartz.plugins.history.LoggingJobHistoryPlugin
org.quartz.plugin.shutdownhook.class = org.quartz.plugins.management.ShutdownHookPlugin
org.quartz.plugin.shutdownhook.cleanShutdown = true

在数据库中导入quartz集群需要的表,这些信息可以从quartz官网下载一个quartz.version.tar.gz, 解压后在doc/dbTables中,找到你数据库的相关文件,

比如mysql可以用 tables_mysql.sql . 导入数据库。

在spring配置文件中定义quartz相关bean和任务






















<bean id="clusterJob" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">  
    <property name="jobClass" value="com.lcg.demo.job.MyDetailQuartzJobBean" />  
    <!-- fail-over 重写执行失败的任务,default=false -->  
    <property name="requestsRecovery" value="false"/>  
     <property name="durability" value="true" />  
</bean>  


<!-- 定期动态创建数据表 -->  
<bean id="clusterTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">  
    <property name="jobDetail" ref="clusterJob"/> 
     <property name="cronExpression" value="0/5 * * * * ?"/>  
</bean>

MyJobFactory (保证spring注入成功)

package com.lcg.demo.job;

import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;

public class MyJobFactory extends org.springframework.scheduling.quartz.SpringBeanJobFactory

{

@Autowired
private AutowireCapableBeanFactory beanFactory;

/**

 * 这里覆盖了super的createJobInstance方法,对其创建出来的类再进行autowire。

 */

@Override

protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {

    Object jobInstance = super.createJobInstance(bundle);

    beanFactory.autowireBean(jobInstance);

    return jobInstance;

}

}

MyDetailQuartzJobBean (任务类)

package com.lcg.demo.job;

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.QuartzJobBean;

import com.lcg.demo.service.DataCenterService;

public class MyDetailQuartzJobBean extends QuartzJobBean{
Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
private DataCenterService dataCenterService;

@Override  
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {  
    logger.info("集群任务开始");
    this.dataCenterService.doMyTask();
} 

// 供bean初始化时使用 bean init-method (tomcat启动时会执行)
 public void initFun(){
        logger.info("集群任务开始");
        this.dataCenterService.doMyTask();
    } 

}

至此完成。

可以将项目打包,同时发布到2个tomcat进行测试。

(测试方法:job里面调用service往表里写数据,带一列为时间。)

0%