Статьи

Начало работы с Quartz Scheduler в базе данных MySQL

Вот несколько простых шагов, которые помогут вам полностью начать работу с Quartz Scheduler в базе данных MySQL с помощью Groovy. Сценарий ниже позволит вам быстро поэкспериментировать с различными настройками конфигурации Quartz, используя внешний файл.

Первый шаг — настроить базу данных с таблицами. Предполагая, что вы уже установили MySQL и имеете доступ для создания базы данных и таблиц.

1
2
3
4
5
6
7
8
bash> mysql -u root -p
 
sql> create database quartz2;
sql> create user 'quartz2'@'localhost' identified by 'quartz2123';
sql> grant all privileges on quartz2.* to 'quartz2'@'localhost';
sql> exit;
 
bash> mysql -u root -p quartz2 < /path/to/quartz-dist/docs/dbTables/tables_mysql.sql

tables_mysql.sql можно найти в загрузке дистрибутива Quartz или непосредственно из их источника здесь . Как только база данных будет запущена, вам нужно написать код для запуска Quartz Scheduler. Вот простой Groovy-скрипт quartzServer.groovy который будет работать как крошечный сервер планировщика.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// Run Quartz Scheduler as a server
// Author: Author: Zemian Deng, Date: 2012-12-15_16:46:09
@GrabConfig(systemClassLoader=true)
@Grab('mysql:mysql-connector-java:5.1.22')
@Grab('org.slf4j:slf4j-simple:1.7.1')
@Grab('org.quartz-scheduler:quartz:2.1.6')
import org.quartz.*
import org.quartz.impl.*
import org.quartz.jobs.*
 
config = args.length > 0 ? args[0] : 'quartz.properties'
scheduler = new StdSchedulerFactory(config).getScheduler()
scheduler.start()
 
// Register shutdown
addShutdownHook {
  scheduler.shutdown()
}
 
// Quartz has its own thread, so now put this script thread to sleep until
// user hit CTRL+C
while (!scheduler.isShutdown()) {
 Thread.sleep(Long.MAX_VALUE)
}

И теперь вам просто нужен файл конфигурации quartz-mysql.properties который выглядит следующим образом:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
# Main Quartz configuration
org.quartz.scheduler.skipUpdateCheck = true
org.quartz.scheduler.instanceName = DatabaseScheduler
org.quartz.scheduler.instanceId = NON_CLUSTERED
org.quartz.scheduler.jobFactory.class = org.quartz.simpl.SimpleJobFactory
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.dataSource = quartzDataSource
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 5
 
# JobStore: JDBC jobStoreTX
org.quartz.dataSource.quartzDataSource.driver = com.mysql.jdbc.Driver
org.quartz.dataSource.quartzDataSource.URL = jdbc:mysql://localhost:3306/quartz2
org.quartz.dataSource.quartzDataSource.user = quartz2
org.quartz.dataSource.quartzDataSource.password = quartz2123
org.quartz.dataSource.quartzDataSource.maxConnections = 8

Вы можете запустить Groovy скрипт как обычно

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
bash> groovy quartzServer.groovy quartz-mysql.properties
Dec 15, 2012 6:20:26 PM com.mchange.v2.log.MLog
 
INFO: MLog clients using java 1.4+ standard logging.
Dec 15, 2012 6:20:27 PM com.mchange.v2.c3p0.C3P0Registry banner
INFO: Initializing c3p0-0.9.1.1 [built 15-March-2007 01:32:31; debug? true; trace:10]
[main] INFO org.quartz.impl.StdSchedulerFactory - Using default implementation for ThreadExecutor
[main] INFO org.quartz.core.SchedulerSignalerImpl - Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl
[main] INFO org.quartz.core.QuartzScheduler - Quartz Scheduler v.2.1.6 created.
[main] INFO org.quartz.core.QuartzScheduler - JobFactory set to: org.quartz.simpl.SimpleJobFactory@1a40247
[main] INFO org.quartz.impl.jdbcjobstore.JobStoreTX - Using thread monitor-based data access locking (synchronization).
[main] INFO org.quartz.impl.jdbcjobstore.JobStoreTX - JobStoreTX initialized.
[main] INFO org.quartz.core.QuartzScheduler - Scheduler meta-data: Quartz Scheduler (v2.1.6) 'DatabaseScheduler' with instanceId 'NON_CLUSTERED'
  Scheduler class: 'org.quartz.core.QuartzScheduler' - running locally.
  NOT STARTED.
  Currently in standby mode.
  Number of jobs executed: 0
  Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 5 threads.
  Using job-store 'org.quartz.impl.jdbcjobstore.JobStoreTX' - which supports persistence. and is not clustered.
 
[main] INFO org.quartz.impl.StdSchedulerFactory - Quartz scheduler 'DatabaseScheduler' initialized from the specified file : 'quartz-mysql.properties' from the class resource path.
[main] INFO org.quartz.impl.StdSchedulerFactory - Quartz scheduler version: 2.1.6
Dec 15, 2012 6:20:27 PM com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource getPoolManager
INFO: Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 3, acquireRetryAttempts
-> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, dataSourceName -> 1hge16k8r18mveoq1iqtotg|1486306, debugUnreturnedConnectionStackTraces -> fals
e, description -> null, driverClass -> com.mysql.jdbc.Driver, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, identityToken -> 1hge16k8r18mveoq1iqtotg|1486306, idleConnectionTestPeriod -> 0, initialPoolSize -> 3, jdbcUrl -> jdbc:mysql://localhost:3306/quartz2, lastAcquisitionFailureDefaultUser -> null, maxAdministrativeTaskTime -> 0
, maxConnectionAge -> 0, maxIdleTime -> 0, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 8, maxStatements -> 0, maxStatementsPerConnection -> 120, minPoolSize -> 1, numHelperThreads -> 3, numThreadsAwaitingCheckoutDefaultUser -> 0, pref
erredTestQuery -> null, properties -> {user=******, password=******}, propertyCycle -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, usesTraditionalReflectiveProxies -> false ]
[main] INFO org.quartz.impl.jdbcjobstore.JobStoreTX - Freed 0 triggers from 'acquired' / 'blocked' state.[main] INFO org.quartz.impl.jdbcjobstore.JobStoreTX - Recovering 0 jobs that were in-progress at the time of the last shut-down.
[main] INFO org.quartz.impl.jdbcjobstore.JobStoreTX - Recovery complete.
[main] INFO org.quartz.impl.jdbcjobstore.JobStoreTX - Removed 0 'complete' triggers.
[main] INFO org.quartz.impl.jdbcjobstore.JobStoreTX - Removed 0 stale fired job entries.
[main] INFO org.quartz.core.QuartzScheduler - Scheduler DatabaseScheduler_$_NON_CLUSTERED started.
 
... CTRL+C
[Thread-6] INFO org.quartz.core.QuartzScheduler - Scheduler DatabaseScheduler_$_NON_CLUSTERED shutting down.
[Thread-6] INFO org.quartz.core.QuartzScheduler - Scheduler DatabaseScheduler_$_NON_CLUSTERED paused.
[Thread-6] INFO org.quartz.core.QuartzScheduler - Scheduler DatabaseScheduler_$_NON_CLUSTERED shutdown complete.

Это полный набор настроек выше. Идите и играйте с другим конфигом. Прочитайте http://quartz-scheduler.org/documentation/quartz-2.1.x/configuration для получения более подробной информации.

Здесь я опубликую пару более простых настроек, которые помогут вам начать работу с обычно используемым набором настроек:

Конфигурация с поддержкой кластера MySQL. При этом вы можете запустить один или несколько терминалов оболочки и запустить другой экземпляр quartzServer.groovy с той же конфигурацией. Все экземпляры кварцевого планировщика должны кластеризоваться и равномерно распределять ваши задания.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
# Main Quartz configuration
org.quartz.scheduler.skipUpdateCheck = true
org.quartz.scheduler.instanceName = DatabaseClusteredScheduler
org.quartz.scheduler.instanceId = AUTO
org.quartz.scheduler.jobFactory.class = org.quartz.simpl.SimpleJobFactory
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.dataSource = quartzDataSource
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.jobStore.isClustered = true
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 5
 
# JobStore: JDBC jobStoreTX
org.quartz.dataSource.quartzDataSource.driver = com.mysql.jdbc.Driver
org.quartz.dataSource.quartzDataSource.URL = jdbc:mysql://localhost:3306/quartz2
org.quartz.dataSource.quartzDataSource.user = quartz2
org.quartz.dataSource.quartzDataSource.password = quartz2123
org.quartz.dataSource.quartzDataSource.maxConnections = 8

Вот еще один конфиг для простого планировщика в памяти.

1
2
3
4
5
6
# Main Quartz configuration
org.quartz.scheduler.skipUpdateCheck = true
org.quartz.scheduler.instanceName = InMemoryScheduler
org.quartz.scheduler.jobFactory.class = org.quartz.simpl.SimpleJobFactory
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 5

Теперь, если вам нужно более модное управление пользовательским интерфейсом Quartz, попробуйте MySchedule .

Счастливого планирования!

Справка: Начало работы с Quartz Scheduler для базы данных MySQL от нашего партнера по JCG Земьяна Дена в блоге журнала A Programmer’s Journal .