2010-07-21 10 views
10

Dans mon application de printemps j'utilise le SchedulerFactoryBean pour intégrer avec Quartz. Nous allons avoir des instances Tomcat en cluster, et donc je veux avoir un environnement Quartz en cluster, de sorte que les mêmes tâches ne s'exécutent pas en même temps sur des serveurs web différents.Quartz & Spring - Clustered mais pas persistant?

Pour ce faire, mon app-context.xml est la suivante:

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

Tout fonctionne bien, sauf que lorsque je tente de supprimer ou modifier un élément déclencheur, puis redémarrez mon application, les anciens déclencheurs sont toujours persisté dans la DB, et toujours courir. Je ne veux pas cela, je veux juste qu'ils soient supprimés lorsque l'application s'arrête (ou est redémarré). J'ai défini la valeur de la propriété overwriteExistingJobs pour être vraie, puisque je pensais que c'est ce qu'elle a fait.

Des idées? Tout ce que je veux utiliser pour la base de données est la mise en grappe, pas n'importe quelle sorte de persistance au-delà de cela.

+0

J'ai eu le même problème et je n'ai pas trouvé de solution. Enfin, j'ai déplacé le travail hors de l'application web et l'a programmé pour fonctionner via cron. Curieux de voir ce que les autres ont à dire. – chedine

+0

Utilisez Terracotta? –

Répondre

2

J'ai fait des recherches sur le sujet et c'est un bug bien connu dans Quartz, j'ai trouvé quelques posts sur leur forum. Pour résoudre ce problème, j'ai créé un bean qui supprime tous les enregistrements de la table Quartz. Vous pouvez appeler ce bean avant que votre bean Quartz soit chargé (ajoutez un "depend-on" sur votre bean Scheduler), lorsque votre contexte Spring est détruit (assurez-vous que le pool de connexions DB est toujours ouvert) ou manuellement via une forme de UI. Il y a aussi un bug sur les groupes de travail, ne soyez pas surpris. Mon premier problème a été de créer un client Quartz avec le correctif, mais il était assez difficile de le mettre à niveau dès qu'il sortait une nouvelle version (j'utilisais 1.4 ou 1.5 à la fois - je ne m'en souviens pas vraiment).

+3

Ce n'est pas un bug. C'est une idée fausse de ce que fait le plugin qui lit le fichier XML. Tout ce qu'il fait lire le fichier et ajouter les emplois/déclencheurs qui sont spécifiés dans le fichier. C'est tout ce qu'il fait à tout moment. Il ne prétend pas faire autre chose que cela (par ex.effacer d'abord toutes les données dans le planificateur). – jhouse

0

Ceci est un ancien article, mais pour le bénéfice de ceux qui ont besoin d'une solution, la voici. Spécifiez "true" pour la propriété "overwriteExistingJobs". Vous devrez redémarrer votre serveur et chaque fois que vous redémarrerez, les anciens travaux seront supprimés. Je ne sais pas si cela était possible dans les anciennes versions de quartz-scheduler, j'utilise 2.1.7

1

J'ai rencontré un problème similaire avec le quartz en cluster 2. Je ne courais pas le chameau, mais c'est le même problème.

1) Il n'y a aucun moyen que j'ai vu pour supprimer les travaux dans un environnement en cluster en supprimant simplement les travaux/déclencheurs du contexte de printemps xml. 2) Étant donné que la base de données stocke les informations sur le travail/déclencheur, le déploiement de déploiements entre les serveurs devient problématique si vous ajoutez ou modifiez des tâches. Les serveurs peuvent commencer à exécuter des travaux avant que l'implémentation du travail puisse être déployée sur le serveur de l'application, à moins que vous ne supprimiez tous les serveurs avant de déployer vos modifications.

Pour résoudre ce problème, j'ai trouvé une solution assez simple. Dans le cadre de notre processus de construction, nous capturions et stockions déjà une version de construction unique + numéro w/dans l'artefact de construction (en utilisant la substitution de variable gradle). Pour résoudre ce problème, nous avons simplement fait en sorte que le nom du planificateur comprenne la version de construction unique + numéro. Cela entraîne l'ajout du dernier ensemble de tâches et de déclencheurs à la base de données sous le nom du nouveau planificateur, et une fois le déploiement par roulement effectué, tous les serveurs s'exécutent sous le nouveau nom. Cela résout le problème d'effacement et résout également le problème de déploiement roulant. Si tous les noms de planificateur supplémentaires deviennent un problème dans la base de données, quelque chose pourrait être écrit pour les nettoyer si nécessaire.