2010-07-21 4 views
10

In meiner Spring-Anwendung verwende ich die SchedulerFactoryBean zur Integration mit Quartz. Wir werden Tomcat-Instanzen gruppiert haben, und daher möchte ich eine Quartz-Cluster-Umgebung haben, damit dieselben Jobs nicht gleichzeitig auf verschiedenen Webservern ausgeführt werden.Quartz & Spring - Geclustert, aber nicht dauerhaft?

Um dies zu tun, mein app-context.xml wie folgt:

<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> 
    <property name="triggers"> 
     <list> 
      <ref bean="cronTrigger"/> 
      <ref bean="simpleTrigger" /> 
     </list> 
    </property> 
    <property name="dataSource" ref="dataSource"/> 
    <property name="overwriteExistingJobs" value="true"/> 
    <!-- found in applicationContext-data.xml --> 
    <property name="applicationContextSchedulerContextKey" value="applicationContext"/> 
    <property name="quartzProperties"> 
     <props> 
      <prop key="org.quartz.scheduler.instanceName">SomeBatchScheduler</prop> 
      <prop key="org.quartz.scheduler.instanceId">AUTO</prop> 
      <prop key="org.quartz.jobStore.misfireThreshold">60000</prop> 
      <!--<prop key="org.quartz.jobStore.class">org.quartz.simpl.RAMJobStore</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.threadPool.class">org.quartz.simpl.SimpleThreadPool</prop> 
      <prop key="org.quartz.threadPool.threadCount">25</prop> 
      <prop key="org.quartz.threadPool.threadPriority">5</prop> 
     </props> 
    </property> 
</bean> 

Alles funktioniert gut, außer dass, wenn ich versuche, einen Auslöser zu löschen oder zu ändern, dann meine Anwendung neu starten, werden die alten Auslöser blieb noch in der DB, und immer noch laufen. Ich möchte das nicht, ich möchte nur, dass sie gelöscht werden, wenn die App stoppt (oder neu gestartet wird). Ich setze den Wert der overwriteExistingJobs Eigenschaft, um wahr zu sein, da ich dachte, dass es das ist, was es getan hat.

Irgendwelche Ideen? Alles, was ich für die DB verwenden möchte, ist das Clustering, nicht irgendeine Art von Persistenz darüber hinaus.

+0

Ich hatte das gleiche Problem und ich konnte keine Lösung finden. Schließlich habe ich den Job aus der Web App verschoben und geplant, dass er über cron läuft. Neugierig zu sehen, was andere zu sagen haben. – chedine

+0

Verwenden Sie Terrakotta? –

Antwort

2

Ich habe Forschung zu dem Thema und das ist ein bekannter Fehler in Quarz, fand ich ein paar Beiträge in ihrem Forum. Um dieses Problem zu lösen, habe ich eine Bean erstellt, die alle Datensätze in der Quartz-Tabelle löscht. Sie können diese Bean aufrufen, bevor Ihre Quartz-Bean geladen wird (fügen Sie eine "Abhängigkeit" von Ihrer Scheduler-Bean hinzu), wenn Ihr Spring-Kontext zerstört wird (stellen Sie sicher, dass der DB-Verbindungspool noch geöffnet ist) oder manuell durch irgendeine Form von Benutzeroberfläche. Es gibt auch einen Fehler bei Jobgruppen, sei nicht überrascht. Meine erste Lösung bestand darin, ein Kunden-Quartz-Glas mit dem Fix zu erstellen, aber es wurde ziemlich schwierig, sie zu aktualisieren, wenn sie eine neue Version veröffentlichten (ich verwendete damals 1.4 oder 1.5 - erinnere mich nicht wirklich).

+3

Dies ist kein Fehler. Es ist ein Missverständnis, was das Plugin, das die XML-Datei liest, tut. Alles, was es tut, liest die Datei und fügt die Jobs/Trigger hinzu, die in der Datei angegeben sind. Das ist alles, was es tut, wenn es läuft. Es behauptet nicht, etwas anderes als das zu tun (z.B.Löschen Sie zunächst alle Daten im Scheduler). – jhouse

0

Dies ist eine alte Post, aber für diejenigen, die eine Lösung benötigen, hier ist es. Geben Sie "true" für die Eigenschaft "overwriteExistingJobs" an. Sie müssen Ihren Server neu starten und bei jedem Neustart werden die alten Jobs entfernt. Ich weiß nicht, ob das in älteren Versionen von Quarz-Scheduler möglich war, ich benutze 2.1.7

1

Ich stieß auf ein ähnliches Problem mit Clustered Quarz 2. Ich lief nicht Kamel, aber es ist das gleiche Problem.

1) Es gibt keine Möglichkeit, die Jobs in einer Clusterumgebung zu löschen, indem einfach die Jobs/Trigger aus dem Spring Context XML entfernt werden.

2) Da die Datenbank Job/Trigger-Informationen speichert, wird das Rolling von Bereitstellungen auf Servern problematisch, wenn Sie Jobs hinzufügen oder ändern. Server können Jobs starten, bevor die Jobimplementierung auf dem Anwendungsserver bereitgestellt werden kann, sofern Sie nicht alle Server vor der Bereitstellung der Änderungen entfernen.

Um dies zu lösen, kam ich auf eine ziemlich einfache Lösung. Als Teil unseres Build-Prozesses haben wir bereits eine einzigartige Build-Version + Nummer w/im Build-Artefakt erfasst und gespeichert (unter Verwendung der Variablenvariablen-Substitution). Um dieses Problem zu lösen, haben wir einfach den Namen des Schedulers mit der eindeutigen Build-Version + Nummer versehen. Dies führt dazu, dass die letzte Gruppe von Jobs + Triggern der Datenbank unter dem Namen des neuen Schedulers hinzugefügt wird, und sobald die Rolling-Bereitstellung abgeschlossen ist, laufen alle Server mit dem neuen Namen. Dies löst das Löschproblem und löst auch das Rolling-Deployment-Problem. Wenn alle zusätzlichen Scheduler-Namen ein Problem in der db werden, könnte etwas geschrieben werden, um sie bei Bedarf zu bereinigen.