Quartz分布式调试任务(一)
如果是用spring的框架,那么quartz的调试任务不会是什么问题,因为spring已经有quartz的相关支持,在spring的xml文件中声明如下,就可以实现调试任务,只需要写任务的执行代码,十分方便,代码大体如下:
- 首先加入maven的依赖
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>${quartz.version}</version>
</dependency>
实际上quartz包中默认有一个配置文件,单机版保持默认即可,quartz.propertes原始文件描述如下:
# Default Properties file for use by StdSchedulerFactory
# to create a Quartz Scheduler Instance, if a different
# properties file is not explicitly specified.
org.quartz.scheduler.instanceName: DefaultQuartzScheduler
org.quartz.scheduler.rmi.export: false
org.quartz.scheduler.rmi.proxy: false
org.quartz.scheduler.wrapJobExecutionInUserTransaction: false
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.simpl.RAMJobStore
- spring描述文件中声明
<!-- 方式一:CronTrigger包含JobDetail,JobDetail用MethodInvokingJobDetailFactoryBean工厂Bean包装普通的Java对象或bean -->
<bean id="job01Trigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail" >
<bean class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<!--执行的类-->
<property name="targetObject" ref="jobService" />
<!--执行的方法-->
<property name="targetMethod" value="job01" />
<property name="concurrent" value="false" />
</bean>
</property>
<property name="cronExpression" value="0/3 * * * * ? *" />
</bean>
###########################################################
<!--方式二:CronTrigger包含JobDetail,JobDetail用JobDetailFactoryBean包装QuartzJobBean的继承子类(即Job类)的实例-->
<bean id="job02Trigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail" >
<bean class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="jobClass" value="com.xxl.job.JobDetailDemo"/>
<property name="jobDataAsMap">
<map>
<!-- <entry key="xxService" value-ref="xxService" /> -->
</map>
</property>
<property name="durability" value="true"></property>
</bean>
</property>
<property name="cronExpression" value="0/1 * * * * ? *" />
</bean>
#############################################################
<!--调试任务-->
<bean name="startQuertz" lazy-init="false" autowire="no" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="job01Trigger" />
</list>
</property>
</bean>
- 实现分布式
集群分布式并发环境中使用QUARTZ定时任务调度,会在各个节点会上报任务,存到数据库中,执行时会从数据库中取出触发器来执行,如果触发器的名称和执行时间相同,则只有一个节点去执行此任务。
如果此节点执行失败,则此任务则会被分派到另一节点执行,中途也会自动检查失效的定时调度,发现不成功的,其他节点立马接过来继续完成定时任务。对应的定时任务调度表比较多,有11个,可以从官方的quartz包中找到。
集群版本,需要copy出jar包中配置,新增如下配置,并注释掉重复配置项目,即可;
# for cluster
org.quartz.scheduler.instanceId: AUTO
org.quartz.jobStore.class: org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.isClustered: true
org.quartz.jobStore.clusterCheckinInterval: 1000
数据库:读取配置在数据库里的job初始化信息,并且把job通过java序列化到数据库里,这样就使得每个job信息得到了持久化,即使在jvm或者容器挂掉的情况下,也能通过数据库感知到其他job的状态和信息;quartz集群各节点之间是通过同一个数据库实例(准确的说是同一个数据库实例的同一套表)来感知彼此的。
<bean id="quartzScheduler" lazy-init="false" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="autoStartup" value="true" />
<property name="applicationContextSchedulerContextKey" value="applicationContextKey" />
<property name="configLocation" value="classpath:quartz.properties"/>
<property name="triggers">
<list>
<ref bean="job02Trigger" />
</list>
</property>
</bean>
注:applicationContextSchedulerContextKey: 是org.springframework.scheduling.quartz.SchedulerFactoryBean这个类中把spring上下 文以key/value的方式存放在了quartz的上下文中了,可以用applicationContextSchedulerContextKey所定义的key得到对应的spring上下文。