По сути, плагины в Quartz — это удобные классы, обертывающие регистрацию базовых слушателей . Вы можете написать свои собственные плагины, но мы сосредоточимся на существующих, поставляемых с Quartz.
LoggingTriggerHistoryPlugin
Сначала немного предыстории. Две основные абстракции в Кварце — рабочие места и триггеры. Работа — это кусок кода, который мы хотели бы запланировать. Trigger указывает планировщику, когда должен выполняться этот код. CRON (например, запускаются каждую пятницу с 9:00 до 17:00 до ноября) и простые (запускаются 100 раз каждые 2 часа) триггеры наиболее часто используются. Вы связываете любое количество триггеров с одной работой.
Верьте или нет, Quartz по умолчанию не обеспечивает ведение журнала или мониторинг выполненных заданий и триггеров. Существует API, но встроенное ведение журнала не реализовано. Он не покажет вам, что теперь он выполняет эту конкретную работу из-за срабатывания триггера. Поэтому первое, что вы должны сделать, это добавить следующие строки в ваш quartz.properties:
1
2
3
4
5
6
7
|
org.quartz.plugin.triggerHistory.class=org.quartz.plugins. history .LoggingTriggerHistoryPlugin org.quartz.plugin.triggerHistory.triggerFiredMessage=Trigger [{1}.{0}] fired job [{6}.{5}] scheduled at: {2, date , dd -MM-yyyy HH:mm:ss.SSS}, next scheduled at: {3, date , dd -MM-yyyy HH:mm:ss.SSS} org.quartz.plugin.triggerHistory.triggerCompleteMessage=Trigger [{1}.{0}] completed firing job [{6}.{5}] with resulting trigger instruction code: {9}. Next scheduled at: {3, date , dd -MM-yyyy HH:mm:ss.SSS} org.quartz.plugin.triggerHistory.triggerMisfiredMessage=Trigger [{1}.{0}] misfired job [{6}.{5}]. Should have fired at: {3, date , dd -MM-yyyy HH:mm:ss.SSS} |
Первая строка (и единственная обязательная) загружает класс плагина LoggingTriggerHistoryPlugin. Остальные строки настраивают плагин, настраивая сообщения регистрации. Я обнаружил, что встроенные значения по умолчанию не очень хорошо продуманы, например, они отображают текущее время, которое уже является частью сообщения каркаса логирования. Вы можете создать любое сообщение регистрации, подробности см. В API. Добавление этих нескольких дополнительных строк значительно упрощает отладку и мониторинг:
1
2
3
|
LoggingTriggerHistoryPlugin | Trigger [Demo.Every-few-seconds] fired job [Demo.Print-message] scheduled at: 04-04-2012 23:23:47.036, next scheduled at: 04-04-2012 23:23:51.036 // ...job output LoggingTriggerHistoryPlugin | Trigger [Demo.Every-few-seconds] completed firing job [Demo.Print-message] with resulting trigger instruction code: DO NOTHING. Next scheduled at: 04-04-2012 23:23:51.036 |
Теперь вы понимаете, почему так важно присвоить имена своим триггерам (Demo.Every-two-seconds) и заданиям (Demo.Print-message).
LoggingJobHistoryPlugin
Есть еще один удобный плагин, связанный с регистрацией:
1
2
3
4
5
|
org.quartz.plugin.jobHistory.class=org.quartz.plugins. history .LoggingJobHistoryPlugin org.quartz.plugin.jobHistory.jobToBeFiredMessage=Job [{1}.{0}] to be fired by trigger [{4}.{3}], re-fire: {7} org.quartz.plugin.jobHistory.jobSuccessMessage=Job [{1}.{0}] execution complete and reports: {8} org.quartz.plugin.jobHistory.jobFailedMessage=Job [{1}.{0}] execution failed with exception: {8} org.quartz.plugin.jobHistory.jobWasVetoedMessage=Job [{1}.{0}] was vetoed. It was to be fired by trigger [{4}.{3}] at: {2, date , dd -MM-yyyy HH:mm:ss.SSS} |
Правило то же самое — плагин + дополнительная настройка. Посмотрите JavaDoc LoggingJobHistoryPlugin для деталей и возможных заполнителей. Быстрый просмотр журналов показывает очень описательный вывод:
1
2
3
4
5
|
Trigger [Demo.Every-few-seconds] fired job [Demo.Print-message] scheduled at: 04-04-2012 23:34:53.739, next scheduled at: 04-04-2012 23:34:57.739 Job [Demo.Print-message] to be fired by trigger [Demo.Every-few-seconds], re-fire: 0 // ...job output Job [Demo.Print-message] execution complete and reports: null Trigger [Demo.Every-few-seconds] completed firing job [Demo.Print-message] with resulting trigger instruction code: DO NOTHING. Next scheduled at: 04-04-2012 23:34:57.739 |
Я понятия не имею, почему эти плагины не включены по умолчанию. В конце концов, если вам не нужен такой подробный вывод, вы можете отключить его в своей структуре ведения журналов. Не берите в голову, я думаю, что это хорошая идея, чтобы иметь их на месте при устранении неполадок исполнения Quartz.
XMLSchedulingDataProcessorPlugin
Это довольно полный плагин. Он читает XML-файл (по умолчанию с именем quartz_data.xml), содержащий задания, и запускает определения и добавляет их в планировщик. Это особенно полезно, когда у вас есть глобальная работа, которую нужно добавить один раз. Плагин может либо обновить существующие задания / триггеры, либо игнорировать файл XML, если они уже существуют, — очень полезно, когда используется JDBCJobStore .
1
|
org.quartz.plugin.xmlScheduling.class=org.quartz.plugins.xml.XMLSchedulingDataProcessorPlugin |
В вышеупомянутой статье мы вручную добавляли работу в планировщик:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
|
val trigger = newTrigger(). withIdentity( "Every-few-seconds" , "Demo" ). withSchedule( simpleSchedule(). withIntervalInSeconds( 4 ). repeatForever() ). build() val job = newJob(classOf[PrintMessageJob]). withIdentity( "Print-message" , "Demo" ). usingJobData( "msg" , "Hello, world!" ). build() scheduler.scheduleJob(job, trigger) |
То же самое может быть достигнуто с помощью конфигурации XML, просто поместите следующий файл quartz_data.xml в ваш CLASSPATH:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
<? xml version = "1.0" encoding = "UTF-8" ?> xsi:schemaLocation = " http://www.quartz-scheduler.org/xml/JobSchedulingData http://www.quartz-scheduler.org/xml/job_scheduling_data_2_0.xsd " > < processing-directives > < overwrite-existing-data >false</ overwrite-existing-data > < ignore-duplicates >true</ ignore-duplicates > </ processing-directives > < schedule > < trigger > < simple > < name >Every-few-seconds</ name > < group >Demo</ group > < job-name >Print-message</ job-name > < job-group >Demo</ job-group > < repeat-count >-1</ repeat-count > < repeat-interval >4000</ repeat-interval > </ simple > </ trigger > < job > < name >Print-message</ name > < group >Demo</ group > < job-class >com.blogspot.nurkiewicz.quartz.demo.PrintMessageJob</ job-class > < job-data-map > < entry > < key >msg</ key > < value >Hello, World!</ value > </ entry > </ job-data-map > </ job > </ schedule > </ job-scheduling-data > |
То же самое может быть достигнуто с помощью конфигурации XML, просто поместите следующий файл quartz_data.xml в ваш CLASSPATH:
1
2
|
org.quartz.plugin.xmlScheduling.fileNames= /etc/quartz/system-jobs .xml, /home/johnny/my-jobs .xml org.quartz.plugin.xmlScheduling.scanInterval=60 |
ShutdownHookPlugin
Наконец, что не менее важно, ShutdownHookPlugin. Небольшой, но, вероятно, полезный плагин, который регистрирует отключение в JVM, чтобы аккуратно остановить планировщик. Однако я рекомендую отключить cleanShutdown — если система уже пытается внезапно остановить приложение (обычно завершение работы планировщика вызывается Spring через SchedulerFactoryBean) или пользователь нажимает Ctrl + C — ожидание текущих выполняемых заданий кажется плохой идеей. В конце концов, может быть, мы убиваем приложение, потому что некоторые задания выполняются слишком долго / слишком долго?
1
2
|
org.quartz.plugin.shutdownHook.class=org.quartz.plugins.management.ShutdownHookPlugin org.quartz.plugin.shutdownHook.cleanShutdown= false |
Как вы можете видеть корабли Qurtz с несколькими довольно интересными плагинами. По некоторым причинам они не описаны подробно в официальной документации, но они работают довольно хорошо и являются ценным дополнением к планировщику.
Исходный код с примененными плагинами доступен на GitHub.
Ссылка: Кварцевые плагины планировщика — скрытое сокровище от нашего партнера JCG Томаша Нуркевича в блоге Java и соседей .