[size=medium]
java web开发当中常用到定时任务,说到定时任务相信你一定或多或少了解quartz。在单台应用服务器上配置spring + quartz没有什么问题,这样的文章网络上应该也有很多,但是当你把应用放到集群环境中则会出问题,每台服务器上的定时任务并不知道其他服务器上的定时 任务的存在,各自执行产生资源竞争,可能就会导致出现脏数据。
本篇文章讲解了如何在集群环境中配置定时任务,用到的是spring4 + quartz2.2.1,下面请跟我一步一步进行配置。
如果你使用maven,添加引入;否则可以官网下载最新包。[/size]
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
[size=medium] 1.新建定时任务执行java类TestJob,集成了QuartzJobBean并实现了executeInternal方法。[/size]
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
public class TestJob extends QuartzJobBean{
@Override
protected void executeInternal(JobExecutionContext context)
throws JobExecutionException {
System.out.pringln("定时任务执行成功");
}
}
2.新建quartz.xml配置文件,并在spring配置文件中添加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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--
定时任务,此处使用JobDetailFactoryBean而非MethodInvokingJobDetailFactoryBean,是因为MethodInvokingJobDetailFactoryBean存在序列化bug。
如果你的项目中使用了MethodInvokingJobDetailFactoryBean,并且不想对此进行修改,可以草考该篇文章:http://mushme.iteye.com/blog/1874370
-->
<bean id="jobDetail" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="jobClass" value="你的项目包路径.TestJob" />
</bean>
<!--
定义job执行逻辑,此处定义0 0 6,20 * * ?,表示每天上午6点,下午8点执行。具体配置方法请自行搜索cronExpression
-->
<bean id="jobTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail" ref="jobDetail" />
<property name="cronExpression" value="0 0 6,20 * * ?" />
</bean>
<!-- 总调度用于启动Spring定时器 -->
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<!--
虽然terracotta买下了quartz,quartz已经支持terracotta集群配置,但是此篇文章依旧使用数据库支持quartz集群的方式
项目已经配置了数据源,此处直接引用
-->
<property name="dataSource">
<ref bean="dataSource" />
</property>
<property name="applicationContextSchedulerContextKey" value="applicationContextKey"/>
<!-- quartz配置文件 -->
<property name="configLocation" value="classpath:quartz.properties" />
<property name="triggers">
<list>
<ref bean="jobTrigger" />
</list>
</property>
</bean>
</beans>
[size=medium]在spring配置文件中引入quartz.xml。
3.上面的配置文件中引入了quartz.properties,我们在src下新建此文件,并加入以下内容。[/size]
#============================================================================
# Configure Main Scheduler Properties
#============================================================================
#\u552F\u4E00\u6807\u8BC6\uFF0C\u540C\u4E00\u4E2A\u96C6\u7FA4\u7684\u540D\u79F0\u5FC5\u987B\u4E00\u81F4
org.quartz.scheduler.instanceName = MyClusteredScheduler
#auto\uFF0C\u5219quartz\u4F1A\u6839\u636E\u65F6\u95F4\u548C\u4E3B\u673A\u540D\u751F\u6210\uFF0C\u786E\u4FDD\u552F\u4E00
org.quartz.scheduler.instanceId = AUTO
#============================================================================
# Configure ThreadPool
#============================================================================
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 25
org.quartz.threadPool.threadPriority = 5
#============================================================================
# Configure JobStore
#============================================================================
org.quartz.jobStore.misfireThreshold = 60000
#jobstoretx\u5219\u4EFB\u52A1\u4F1A\u88AB\u6301\u4E45\u5316\u5230\u6570\u636E\u4E2D\uFF0C\u9ED8\u8BA4\u4E3ARAMJobStore\uFF0C\u9ED8\u8BA4\u4F1A\u88AB\u7EF4\u62A4\u5230\u5185\u5B58\u4E2D\uFF0C\u96C6\u7FA4\u7684\u65F6\u5019\u5FC5\u987B\u4FEE\u6539
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.tablePrefix = QRTZ_
#ture\u5219\u6B64\u5B9E\u4F8B\u9700\u8981\u53C2\u52A0\u5230\u96C6\u7FA4\u4E2D
org.quartz.jobStore.isClustered = true
org.quartz.jobStore.clusterCheckinInterval = 20000
[size=medium] 4.此篇文章讲的是基于数据库的quartz集群,还缺少quartz集群所需要的表,在最新的quartz包中可以找到建表sql,如果你闲麻烦,那就找找文本的附件吧。
当你创建了quartz集群锁需要的表,并且进行了以上配置,就可以启动项目验证quartz集群是否可以正常运行了。
PS:有不明白的地方欢迎留言,如果此篇文章对你有帮助请赞一下,欢迎分享。[/size]