1.准备环境(以maven为例,如果不是请自行下载需要的jar包)
<!-- quartz定时调度器 --> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.3.0</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.43</version> </dependency>配置这个集群需要建立数据库的表,去quartz的官网去下载他的包,解压之后在D:\软件开发\环境软件\quartz-2.2.3-distribution\quartz-2.2.3\docs\dbTables这个目录下面有很多个sql文件,我的是mysql所以我选择的是:tables_mysql_innodb.sql,拿到这个sql文件之后就可以在数据库执行了。
2.配置spring-quartz.properties
org.quartz.scheduler.instanceName = TestScheduler1 org.quartz.scheduler.instanceId = AUTO org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool org.quartz.threadPool.threadCount = 10 org.quartz.threadPool.threadPriority = 5 org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true org.quartz.jobStore.misfireThreshold = 60000 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.maxMisfiresToHandleAtATime=10 org.quartz.jobStore.isClustered = true org.quartz.jobStore.clusterCheckinInterval = 200003.配置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"> <!-- 自定义jobFactory,解决job中无法注入service的问题 --> <bean id="jobFactory" class="com.mayi.common.Quartz.MyJobFactory" /> <!-- 配置任务bean类 --> <!-- <bean id="scheduledJob" class="com.mayi.common.Quartz.FirstScheduledJob"></bean>--> <!-- 配置方法映射工厂类 --> <!-- MethodInvokingJobDetailFactoryBean不支持序列化 --> <!-- concurrent : false表示等上一个任务执行完后再开启新的任务 --> <!-- <bean id="jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <property name="targetObject" ref="quartzTask"></property> <property name="targetMethod" value="startTask"></property> <property name="concurrent" value="false"></property> </bean> --> <bean id="jobDetail" class="org.springframework.scheduling.quartz.JobDetailFactoryBean"> <property name="jobClass" value="com.mayi.common.Quartz.FirstScheduledJob"></property> <property name="durability" value="true"></property> <property name="requestsRecovery" value="true"/> </bean> <!-- 配置任务高度的的时间/周期 --> <bean id="jobTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="jobDetail" ref="jobDetail"></property> <property name="cronExpression" value="*/1 * * * * ?"></property> <!-- <property name="startDelay" value="3000"></property> --> </bean> </beans> 4.在spring-context.xml文件中加入下面的配置,并将 spring-quartz.xml和spring-quartz.properties引入到主配置文件中(这个不会的请自己去找相关spring的资料去学习) <!-- 定时调度工厂 --> <beans:bean id="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <beans:property name="dataSource" ref="mixDataSource_push"></beans:property> <!-- 引入自定义的bean --> <beans:property name="jobFactory" ref="jobFactory" /> <!--可选,QuartzScheduler 启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了 --> <beans:property name="overwriteExistingJobs" value="true"/> <!--必须的,QuartzScheduler 延时启动,应用启动完后 QuartzScheduler 再启动 --> <beans:property name="startupDelay" value="3"/> <!-- 设置自动启动 --> <beans:property name="autoStartup" value="true"/> <beans:property name="applicationContextSchedulerContextKey" value="applicationContextKey"/> <beans:property name="configLocation" value="classpath:spring-quartz.properties"/> <beans:property name="triggers"> <beans:list> <beans:ref bean="jobTrigger"/> </beans:list> </beans:property> </beans:bean> <beans:import resource="classpath:spring-quartz.xml" /> 5.初次之外还需两个类,一个是自定义的jobFactory,一个是FirstScheduledJob;
package com.mayi.common.Quartz; import org.quartz.spi.TriggerFiredBundle; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.AutowireCapableBeanFactory; import org.springframework.scheduling.quartz.AdaptableJobFactory; public class MyJobFactory extends AdaptableJobFactory { //这个对象Spring会帮我们自动注入进来,也属于Spring技术范畴. @Autowired private AutowireCapableBeanFactory capableBeanFactory; protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception { //调用父类的方法 Object jobInstance = super.createJobInstance(bundle); //进行注入,这属于Spring的技术,不清楚的可以查看Spring的API. capableBeanFactory.autowireBean(jobInstance); return jobInstance; } } package com.mayi.common.Quartz; import com.mayi.push.dao.TbPushRecordMapper; import com.mayi.push.dao.TbSocketRecordMapper; import com.mayi.push.data.model.TbSocketRecord; import com.mayi.push.data.model.TbSocketRecordExample; import com.mayi.thirdparty.PushFactory; import org.quartz.DisallowConcurrentExecution; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.quartz.PersistJobDataAfterExecution; 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.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; @Component @PersistJobDataAfterExecution @DisallowConcurrentExecution // 不允许并发执行 public class FirstScheduledJob extends QuartzJobBean { private static final Logger logger = LoggerFactory.getLogger(FirstScheduledJob.class); @Override protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException { try { //执行你自己的任务 } catch (ParseException e) { logger.error("FirstScheduledJob(定时器任务):"+e.getMessage()); } } } 说明:这样就实现了多台服务器的quartz的集群,原理是一台服务器在运行定时任务的时候,其他服务器是无法运行的,直到本台服务器挂掉或者断掉,其他两台中的一台会接管继续执行。
