java web开发当中常用到定时任务,说到定时任务相信你一定或多或少了解quartz。在单台应用服务器上配置spring + quartz没有什么问题,这样的文章网络上应该也有很多,但是当你把应用放到集群环境中则会出问题,每台服务器上的定时任务并不知道其他服务器上的定时 任务的存在,各自执行产生资源竞争,可能就会导致出现脏数据。
本篇文章讲解了如何在集群环境中配置定时任务,用到的是spring4 + quartz2.2.1,下面请跟我一步一步进行配置。
如果你使用maven,添加引入;否则可以官网下载最新包。
<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>
1.新建定时任务执行java类TestJob,集成了QuartzJobBean并实现了executeInternal方法。
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>
在spring配置文件中引入quartz.xml。
3.上面的配置文件中引入了quartz.properties,我们在src下新建此文件,并加入以下内容。
#============================================================================ # 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
4.此篇文章讲的是基于数据库的quartz集群,还缺少quartz集群所需要的表,在最新的quartz包中可以找到建表sql,如果你闲麻烦,那就找找文本的附件吧。
当你创建了quartz集群锁需要的表,并且进行了以上配置,就可以启动项目验证quartz集群是否可以正常运行了。
PS:有不明白的地方欢迎留言,如果此篇文章对你有帮助请赞一下,欢迎分享。