Кварц и пружина — сгруппированы, но НЕ стойки?

В моем приложении Spring я использую SchedulerFactoryBean для интеграции с Quartz. У нас будут кластерные экземпляры Tomcat, и поэтому я хочу иметь кластерную среду Quartz, чтобы одни и те же задания не выполнялись одновременно на разных веб-серверах.

Для этого мой app-context.xml выглядит следующим образом:

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

Все работает хорошо, за исключением того, что когда я пытаюсь удалить или изменить триггер, а затем перезапускаю свое приложение, старые триггеры все еще сохраняются в БД и продолжают работать. Я не хочу этого, я просто хочу, чтобы они удалялись, когда приложение останавливается (или перезапускается). Я установил значение свойства overwriteExistingJobs равным true, так как я думал, что это то, что он делает.

Есть идеи? Все, для чего я хочу использовать БД, - это кластеризация, а не какое-либо постоянство, кроме этого.


person Jason Fotinatos    schedule 21.07.2010    source источник
comment
У меня была такая же проблема, и я не мог найти никакого решения. Наконец, я перенес задание из веб-приложения и запланировал его запуск через cron. Любопытно посмотреть, что скажут другие.   -  person chedine    schedule 21.07.2010


Ответы (3)


Я провел исследование по этой теме, и это известная ошибка в Quartz, я нашел несколько сообщений на их форуме. Чтобы решить эту проблему, я создал компонент, который удаляет все записи в таблице Quartz. Вы можете вызвать этот bean-компонент до того, как ваш Quartz bean-компонент будет загружен (добавьте «зависит от» в ваш компонент планировщика), когда ваш контекст spring будет уничтожен (убедитесь, что пул соединений с БД все еще открыт) или вручную через какую-либо форму Пользовательский интерфейс. Так же есть баг с группами заданий, не удивляйтесь. Мое первое исправление состояло в том, чтобы создать клиентскую банку Quartz с этим исправлением, но было довольно сложно обновляться всякий раз, когда они выпускали новую версию (в то время я использовал 1.4 или 1.5 - точно не помню).

person Felipe Oliveira    schedule 15.08.2010
comment
Это не ошибка. Это неправильное представление о том, что делает плагин, который читает файл XML. Все, что он делает, это читает файл и добавляет задания/триггеры, указанные в файле. Это все, что он делает каждый раз, когда он работает. Он не претендует на что-то другое, кроме этого (например, сначала очистить все данные в планировщике). - person jhouse; 20.10.2011

Я столкнулся с аналогичной проблемой с кластерным кварцем 2. У меня не было верблюда, но проблема та же.

1) Я не видел способа удалить задания в кластерной среде, просто удалив задания/триггеры из XML-контекста spring.

2) Поскольку в базе данных хранится информация о задании/триггере, последовательные развертывания между серверами становятся проблематичными, если вы добавляете или изменяете задания. Серверы могут запускать задания до того, как реализация задания может быть развернута на сервере приложений, если только вы не отключите все серверы перед развертыванием своих изменений.

Чтобы решить эту проблему, я придумал довольно простое решение. В рамках нашего процесса сборки мы уже собирали и сохраняли уникальную версию сборки + номер с артефактом сборки (используя подстановку переменных gradle). Чтобы решить эту проблему, мы просто добавили в имя планировщика уникальную версию + номер сборки. Это приводит к тому, что последний набор заданий + триггеров добавляется в базу данных под именем нового планировщика, и после завершения непрерывного развертывания все серверы работают с новым именем. Это решает проблему удаления, а также решает проблему непрерывного развертывания. Если все дополнительные имена планировщика станут проблемой в базе данных, при необходимости можно будет написать что-то для их очистки.

person angrycrab    schedule 16.09.2015

Это старый пост, но для тех, кому нужно решение, вот оно. Укажите «true» для свойства «overwriteExistingJobs». Вам придется перезапустить сервер, и при каждом перезапуске старые задания будут удаляться. Не знаю, было ли это возможно в старых версиях кварца-планировщика, я использую 2.1.7

person Jayz    schedule 22.05.2013