2010-07-21 12 views
10

Nella mia applicazione Spring sto usando il SchedulerFactoryBean da integrare con Quartz. Avremo cluster di istanze Tomcat e quindi voglio avere un ambiente Quartz in cluster, in modo che gli stessi lavori non vengano eseguiti contemporaneamente su server Web diversi.Quartz & Spring - Raggruppato ma NON persistente?

A tale scopo, il mio app-context.xml è il seguente:

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

Tutto funziona bene, tranne che quando si tenta di rimuovere o modificare un trigger, quindi riavviare la mia app, i vecchi fattori scatenanti sono ancora persistenti nel DB, e ancora eseguito. Non voglio questo, voglio solo che vengano cancellati quando l'app si ferma (o viene riavviata). Ho impostato il valore della proprietà overwriteExistingJobs come vero, poiché ho pensato che fosse ciò che ha fatto.

Qualche idea? Tutto ciò che voglio usare per il DB è il clustering, non una sorta di persistenza al di là di questo.

+0

Ho avuto lo stesso problema e non sono riuscito a trovare alcuna soluzione. Alla fine ho spostato il lavoro fuori dall'app Web e pianificato l'esecuzione tramite cron. Curioso di vedere cosa hanno da dire gli altri. – chedine

+0

Usa la terracotta? –

risposta

2

Ho svolto ricerche sull'argomento e si tratta di un bug noto in Quarzo, ho trovato alcuni post nel loro forum. Per risolvere questo problema ho creato un bean che cancella tutti i record nella tabella Quartz. Puoi chiamare questo bean prima che il tuo Quartz bean sia caricato (aggiungi un "depend-on" sul tuo bean Scheduler), quando il tuo contesto di primavera viene distrutto (assicurati che il pool di connessioni DB sia ancora aperto), o manualmente attraverso qualche forma di UI. C'è anche un bug sui gruppi di lavoro, non essere sorpreso. La mia prima correzione è stata quella di creare un vaso Quartz per il cliente con la correzione, ma è diventato piuttosto difficile aggiornarlo ogni volta che rilasciavano una nuova versione (stavo usando 1.4 o 1.5 al momento).

+3

Questo non è un bug. È un'idea sbagliata di ciò che fa il plugin che legge il file XML. Tutto ciò legge il file e aggiunge i lavori/i trigger che sono specificati nel file. Questo è tutto ciò che fa in qualsiasi momento. Non pretende di fare nient'altro che quello (ad es.prima cancellare tutti i dati nello scheduler). – jhouse

0

Questo è un vecchio post, ma a beneficio di chi ha bisogno di una soluzione, eccolo. Specificare "true" per la proprietà "overwriteExistingJobs". Dovrai riavviare il tuo server e ogni volta che riavvierai, i vecchi lavori verranno rimossi. Non so se questo fosse possibile nelle versioni precedenti di Quartz-Scheduler, sto usando 2.1.7

1

Mi sono imbattuto in un problema simile con il quarzo cluster 2. Non stavo correndo cammello, ma è lo stesso problema.

1) Non c'è modo in cui ho visto cancellare i lavori in un ambiente cluster semplicemente rimuovendo i lavori/i trigger dal contesto xml di primavera.

2) Poiché il database memorizza le informazioni di processo/trigger, le distribuzioni a rotazione su server diventano problematiche se si aggiungono o si modificano lavori. I server possono iniziare a eseguire i lavori prima che l'implementazione del lavoro possa essere distribuita al server delle app, a meno che non si eliminino tutti i server prima di distribuire le modifiche.

Per risolvere questo, ho trovato una soluzione piuttosto semplice. Come parte del nostro processo di compilazione, stavamo già acquisendo e archiviando una versione di build univoca + numero w/nel build art (usando la sostituzione della variabile gradle). Per risolvere questo problema, abbiamo semplicemente fatto in modo che il nome dello schedulatore includesse la versione + numero di build univoca. Ciò si traduce nell'ultimo set di job + trigger aggiunti al db con il nome del nuovo scheduler, e una volta eseguita la distribuzione rolling, tutti i server eseguono con il nuovo nome. Questo risolve il problema dell'eliminazione e risolve anche il problema della distribuzione a rotazione. Se tutti i nomi degli scheduler aggiuntivi diventano un problema nel db, è possibile scrivere qualcosa per pulirli se necessario.