最近项目用到定时任务,之前的做法是用spring quartz的注解形式的定时任务去处理,但采取分布式环境后,定时任务需要避免重复执行,于是引入quartz分布式,大致配置如下:
用的时候注意版本,spring3.x以上需要用quartz2.x以上,
下载quartz.2.1.7.tar.gz到官网下载就可以
解压后找到quartz-2.1.7\docs\dbTables路径下的tables_mysql.sql文件把sql导入到数据库中
然后导入quartz.properties文件
#============================================================================ # Configure Main Scheduler Properties #============================================================================ org.quartz.scheduler.instanceName = TestScheduler org.quartz.scheduler.instanceId = AUTO org.quartz.scheduler.skipUpdateCheck = true #============================================================================ # Configure ThreadPool #============================================================================ org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool org.quartz.threadPool.threadCount = 12 org.quartz.threadPool.threadPriority = 5 #============================================================================ # Configure JobStore #============================================================================ org.quartz.jobStore.misfireThreshold = 60000 #org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate org.quartz.jobStore.dataSource = myDS org.quartz.jobStore.useProperties = false org.quartz.jobStore.tablePrefix = QRTZ_ org.quartz.jobStore.isClustered = true #============================================================================ # Configure Datasources #============================================================================ org.quartz.dataSource.myDS.driver = com.mysql.jdbc.Driver org.quartz.dataSource.myDS.URL = xxx org.quartz.dataSource.myDS.user = xxxx org.quartz.dataSource.myDS.password =xxx org.quartz.dataSource.myDS.maxConnections = 15
先新建一个定时任务需要继承QuartzJobBean、
package com.remair.hx.schedule.quarz; import com.remair.hx.cache.RedisCache; import com.remair.hx.constants.RedisCacheRootKeyConstants; import com.remair.hx.mapper.ConnectLogMapper; import com.remair.hx.mapper.LiveInfoMapper; import com.remair.hx.mapper.LiveUserMapper; import com.remair.hx.mapper.UserMapper; import com.remair.hx.model.LiveUserSchedule; import com.remair.hx.thread.TimeOutUserThread; import com.remair.hx.utils.DateUtil; import org.quartz.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.quartz.QuartzJobBean; import org.springframework.stereotype.Component; import java.util.ArrayList; import java.util.Date; import java.util.List; /** * Created by caige on 2016/6/10. */ @Component @PersistJobDataAfterExecution @DisallowConcurrentExecution public class HeartScheduleJob extends QuartzJobBean { Logger logger = LoggerFactory.getLogger(this.getClass()); @Autowired LiveInfoMapper liveInfoMapper; @Override protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException { //具体的方法逻辑 } } 因为quartz会自己去维护一套容器,所以spring的对象在这失效,比如上边类中注入的liveInfoMapper 失效,所以加入一个类解决此问题:此类在配置quartz.xml中的时候会引入package com.remair.hx.schedule.quarz; import org.quartz.spi.TriggerFiredBundle; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.AutowireCapableBeanFactory; import org.springframework.scheduling.quartz.SpringBeanJobFactory; /** * Created by caige on 2016/6/14. */ public class MyJobFactory extends SpringBeanJobFactory { @Autowired private AutowireCapableBeanFactory beanFactory; @Override protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception { Object jobInstance = super.createJobInstance(bundle); beanFactory.autowireBean(jobInstance); return jobInstance; } }<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd"> <beans> <bean name="startQuertz" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" lazy-init="false" autowire="no"> <property name="configLocation" value="classpath:quartz.properties" /> <property name="jobDetails"> <list> <ref bean="heartDetail"/> </list> </property> <property name="triggers"> <list> <ref bean="heartTime"/> </list> </property> <property name="applicationContextSchedulerContextKey" value="contextConfigLocation"/> //此处用来避免spring管理的对象注入不进去的问题 <property name="jobFactory"> <bean class="com.remair.hx.schedule.quarz.MyJobFactory" /> </property> </bean> <bean id="heartDetail" class="org.springframework.scheduling.quartz.JobDetailFactoryBean"> <property name="jobClass" value="com.remair.hx.schedule.quarz.HeartScheduleJob"/> <property name="durability" value="true" /> <property name="requestsRecovery" value="true" /> </bean> <bean id="heartTime" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="jobDetail" ref="heartDetail"/> <property name="cronExpression" value="0/30 * * * * ?"/> </bean> </beans>
在web.xml中加入对quartz.xml的解析<!-- 读取spring配置文件 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml,classpath:quartz.xml</param-value> </context-param>
因为文笔不好,所以很多点没写出,如果有相同问题欢迎评论,我看到会及时回复的。