Могу ли я вызвать ожидание Quartz Jobs в том порядке, в котором они были запущены? - PullRequest
9 голосов
/ 23 июля 2010

У меня есть приложение, использующее Quartz Scheduler для планирования заданий. Приложение в настоящее время работает под управлением версии Quartz 1.6.2. Мой JobStore - org.quartz.impl.jdbcjobstore.JobStoreTX с поддержкой базы данных Oracle. Кластеризация включена, но есть только один планировщик, использующий базу данных. Мой Quartz threadPool настроен следующим образом:

org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 5
org.quartz.threadPool.threadPriority = 5

Мои задания выполняются долго, поэтому при запуске новых заданий довольно часто работают 5 заданий (максимум, разрешенный моим пулом thead). Вновь запущенные задания пропускаются, и я вижу сообщения в журнале, подобные следующему:

2011-05-20 04:09:30,097 INFO  [QuartzScheduler_scheduler-servername-111305822374881_MisfireHandler] o.q.p.h.LoggingTriggerHistoryPlugin - Trigger DEFAULT.JobName1 misfired job DEFAULT.DEFAULT  at:  04:09:30 05/20/2011.  Should have fired at:  04:08:29 05/20/2011
2011-05-20 04:09:30,120 INFO  [QuartzScheduler_scheduler-servername-111305822374881_MisfireHandler] o.q.p.h.LoggingTriggerHistoryPlugin - Trigger DEFAULT.JobName1 misfired job DEFAULT.DEFAULT  at:  04:09:30 05/20/2011.  Should have fired at:  04:09:30 05/20/2011
2011-05-20 04:09:30,125 INFO  [QuartzScheduler_scheduler-servername-111305822374881_MisfireHandler] o.q.p.h.LoggingTriggerHistoryPlugin - Trigger DEFAULT.JobName2 misfired job DEFAULT.DEFAULT  at:  04:09:30 05/20/2011.  Should have fired at:  04:08:30 05/20/2011
2011-05-20 04:09:30,138 INFO  [QuartzScheduler_scheduler-servername-111305822374881_MisfireHandler] o.q.p.h.LoggingTriggerHistoryPlugin - Trigger DEFAULT.JobName2 misfired job DEFAULT.DEFAULT  at:  04:09:30 05/20/2011.  Should have fired at:  04:09:30 05/20/2011
2011-05-20 04:11:29,998 INFO  [QuartzScheduler_scheduler-servername-111305822376676_MisfireHandler] o.q.impl.jdbcjobstore.JobStoreTX - Handling 2 trigger(s) that missed their scheduled fire-time.

Как только выполняемое задание заканчивается, одно из пропущенных заданий будет подхвачено и выполнено в обычном режиме. Тем не менее, похоже, что Quartz выбирает случайное задание случайным образом, независимо от порядка выполнения заданий. В идеале я бы хотел, чтобы их подбирали в том порядке, в котором они должны были работать, исходя из их первоначального времени стрельбы.

Можно ли сделать так, чтобы мои ожидающие (пропущенные) задания запускались в том порядке, в котором они были запущены, когда станет доступно пространство в Quartz ThreadPool?

Ответы [ 4 ]

2 голосов
/ 21 апреля 2016

Когда кварц обрабатывает триггер, который пропустил время срабатывания, он обновит nextFireTime триггера.По умолчанию триггер считается пропущенным, если его nextFireTime прошло более 60 секунд.Пропущенные триггеры по-прежнему должны выбираться на основе nextFireTime и порядка приоритетов, но я предполагаю, что это кажется случайным, поскольку некоторые триггеры обновлены, а другие нет.

Я бы предложил увеличить свойство org.quartz.jobStore.misfireThreshold.См. http://www.quartz -scheduler.org / Documentation / quartz-2.x / configuration / ConfigRAMJobStore.html (хотя свойство идентично для всех JobStores).Это должно снизить вероятность повторного планирования ваших триггеров.

2 голосов
/ 11 апреля 2011

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

Кроме того, вы можете рассмотреть возможность увеличения порога пропуска зажигания, что приведет к изменению времени, в течение которогоТриггер может «опоздать», ожидая выполнения потока, прежде чем он будет считаться пропущенным (и к нему применена инструкция пропуска).

Возможно ли заставить мои ожидающие (пропущенные) задания получитьсрабатывает в том порядке, в каком они были запущены, когда станет доступным пространство в Quartz ThreadPool?

Инструкции "ничего не делать" оставят время срабатывания без изменений.

0 голосов
/ 11 мая 2015

В случае CronTrigger метод updateAfterMisfire() может перепланировать задачу на new Date() case MISFIRE_INSTRUCTION_FIRE_ONCE_NOW policy.

Если несколько задач выполняются с ошибкой, некоторые из них могут быть перенесены одновременно (в одну миллисекунду), поскольку компьютер работает быстро.

Как следствие, и если приоритет не определен, планировщик подхватит первую следующую задачу, все с тем же NextFireTime, в соответствии с ключом или полным именем.

updateAfterMisfire() метод должен был переназначить задачу на уникальный date, используя, например, Thread.sleep(25).

0 голосов
/ 10 апреля 2011

Глядя на кварцевый пул потоков , он использует цикл wait () / notify (), который не является справедливым, и будет случайным образом выбирать новый поток, когда несколько потоков ожидают.

Вы можете использовать свой собственный экземпляр ThreadPool, что справедливо.Скопируйте код из SimpleThreadPool, но замените блокировку вокруг nextRunnableLock на java.util.ReentrantLock, передав true в конструкторе fair.В вашем модифицированном SimpleThreadPool используйте ReentrantLock.lock () / unlock () вместо синхронизированного и используйте ReentrantLock.newCondition (). Signal () / await () вместо wait / notify, и это может решить вашу проблему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...