Quartz 2 + spring 4 - 当spring配置为覆盖现有作业时,群集会中断

时间:2014-10-20 10:53:31

标签: java spring quartz-scheduler

我在Quartz中看到一个奇怪的行为,当它在群集模式下配置时,spring被配置为overwriteExistingJobs=true

我的问题是:我的配置有问题吗?可以在群集模式下使用overwriteExistingJobs吗?或者这是Quartz中的一个错误? (因为quartz应该提供集群作业仅在一个节点中运行的不变量)

我有一个每秒触发的SimpleTrigger,它会触发一个用@DisallowConcurrentExecution注释的作业,并打印触发器触发的次数。问题显示我运行时运行应用程序的第二个实例;在这种情况下,使用不同的触发器计数在两个实例上触发作业(我可以在数据库中看到有不同值的更新将转到qrtz_simple_triggers.times_triggered

当我设置属性overwriteExistingJobs=false时,quartz会按预期运行,并且作业仅在群集的一个实例中运行。

我正在使用

  • 用于存储作业的MySQL 5.5(innodb)
  • Spring 4.1.1.RELEASE
  • Quartz 2.2.1

这是我的弹簧配置

<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">

   <bean name="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
      <property name="driverClassName" value="com.mysql.jdbc.Driver" />
      <property name="url" value="jdbc:mysql://localhost:3306/quartz" />
      <property name="username" value="quartz" />
      <property name="password" value="quartz" />
   </bean>

   <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
      <property name="dataSource" ref="dataSource" />
   </bean>

   <bean name="myJobDetails" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
      <property name="jobClass" value="og.test.MyJob"/>
      <property name="durability" value="true"/>
      <property name="name" value="myJobDetails"/>
      <property name="group" value="myJobDetails"/>
   </bean>

   <bean id="myJobDetailsSimpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
      <property name="jobDetail" ref="myJobDetails"/>
      <property name="startDelay" value="2000"/>
      <property name="repeatInterval" value="1000"/>
      <property name="name" value="myJobDetailsSimpleTrigger"/>
      <property name="group" value="myJobDetails"/>
   </bean>

   <bean id="scheduler" class="og.test.TriggerCleaningSchedulerFactoryBean">
      <property name="quartzProperties">
         <props>
            <prop key="org.quartz.scheduler.instanceName">MY_JOB_SCHEDULER</prop>
            <prop key="org.quartz.scheduler.instanceId">AUTO</prop>
            <prop key="org.quartz.jobStore.class">org.quartz.impl.jdbcjobstore.JobStoreTX</prop>
            <prop key="org.quartz.jobStore.driverDelegateClass">org.quartz.impl.jdbcjobstore.StdJDBCDelegate</prop>
            <prop key="org.quartz.jobStore.tablePrefix">QRTZ_</prop>
            <prop key="org.quartz.jobStore.isClustered">true</prop>
            <prop key="org.quartz.jobStore.clusterCheckinInterval">20000</prop>
            <prop key="org.quartz.threadPool.class">org.quartz.simpl.SimpleThreadPool</prop>
            <prop key="org.quartz.threadPool.threadCount">10</prop>
            <prop key="org.quartz.threadPool.threadPriority">5</prop>
         </props>
      </property>
      <property name="dataSource" ref="dataSource"/>
      <property name="transactionManager" ref="transactionManager"/>
      <property name="overwriteExistingJobs" value="true"/>     <!-- offending property -->
      <property name="schedulerName" value="quartzScheduler"/>
      <property name="autoStartup" value="true"/>
      <property name="triggers">
         <list><ref bean="myJobDetailsSimpleTrigger"/></list>
      </property>

      <property name="jobDetails">
         <list><ref bean="myJobDetails" /></list>
      </property>
   </bean>
</beans>

我的工作班

@DisallowConcurrentExecution
public class MyJob extends QuartzJobBean {
   @Override
   protected void executeInternal(JobExecutionContext ctx) throws JobExecutionException {
      String jobName = ctx.getJobDetail().getKey().getName();
      String triggerName = ctx.getTrigger().getKey().getName();
      SimpleTrigger simpleTrigger = (SimpleTrigger) ctx.getTrigger();
      int timesTriggered = simpleTrigger.getTimesTriggered();

      System.out.printf("%d - %s/%s - %d\n", System.currentTimeMillis(), jobName, triggerName, timesTriggered);
   }
}

0 个答案:

没有答案