Требуемый пример кода и конфигурации кластеров Grails для кластеризации кварца - PullRequest
8 голосов
/ 20 сентября 2011

Я использую кварцевый плагин с Grails 1.3.7. Мне нужно балансировать нагрузку / кластеризовать серверное приложение, которое использует кварцевые задания. Очевидно, это поддерживается, но я обнаружил, что все результаты поиска в Google и ссылки в документах не работают. Я нашел несколько простых примеров Java, но я бы предположил, что у Grails есть более простой способ сделать это. Все, что мне нужно, это простой пример для использования в качестве шаблона. Я понимаю, что мне нужно как-то разрешить кварцу использовать JDBC для хранения заданий и управления блокировками.

Я думаю, что ссылка на один образец сделает это. Но буквально каждый раз, когда я находил что-то, что выглядит многообещающе, это указывает на неработающую ссылку на сайте терракоты. Практически каждый сайт в конечном итоге приводит меня сюда: http://www.opensymphony.com/quartz/wikidocs/TutorialLesson9.html, но когда я просматриваю сайт терракоты, я вижу вещи с Java, но без грааля. Если Java - единственный способ сделать это, то пусть так и будет, но я чувствую, что где-то там должен быть какой-то опыт Grails!

ТИА.

Ответы [ 2 ]

13 голосов
/ 20 сентября 2011

Для кластеризации плагина Quartz в Grails, есть несколько файлов, которые необходимо включить в ваш проект.Сначала установите grails-app/conf/QuartzConfig.groovy и убедитесь, что jdbcStore включен.

quartz {
    autoStartup = true
    jdbcStore = true
    waitForJobsToCompleteOnShutdown = true
}

Затем установите файлы конфигурации Hibernate, относящиеся к базе данных, к которой вы будете подключаться.Например, в Oracle базовая конфигурация Hibernate xml на grails-app/conf/hibernate/hibernate.cfg.xml выглядит следующим образом:

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
'-//Hibernate/Hibernate Configuration DTD 3.0//EN'
'http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd'>

<hibernate-configuration>

<session-factory>
    <mapping resource="Quartz.oracle.hbm.xml"/>
</session-factory>

</hibernate-configuration>

Фактический файл Quartz-Hibernate SQL для этого примера будет называться Quartz.oracle.hbm.xml и будет находиться в том же каталоге.Эти файлы должны быть доступны в подключаемом модуле Quartz на GitHub (https://github.com/nebolsin/grails-quartz), в src/templates/sql. Обратите внимание, что эти сценарии работают только для DataSource create и create-drop, поэтому вам нужно будет создать их вручнуютаблицы Quartz в update, если они еще не существуют из предыдущего запуска.

Создайте файл grails-app/conf/quartz/quartz.properties и отредактируйте его в соответствии с потребностями вашего бизнеса:

/* Have the scheduler id automatically generated for
 * all schedulers in a cluster */
org.quartz.scheduler.instanceId = AUTO
/* Don't let Quartz "Phone Home" to see if new versions
 * are available */
org.quartz.scheduler.skipUpdateCheck = true

org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
/* Configure Quartz for only one thread as the only job
 * should run once per day */
org.quartz.threadPool.threadCount = 4
/* Give the thread a Thread.MIN_PRIORITY level*/
org.quartz.threadPool.threadPriority = 1

/* Allow a minute (60,000 ms) of non-firing to pass before 
 * a trigger is called a misfire */
org.quartz.jobStore.misfireThreshold = 60000
/* Handle only 2 misfired triggers at a time */
org.quartz.jobStore.maxMisfiresToHandleAtATime = 2
/* Check in with the cluster every 5000 ms*/
org.quartz.jobStore.clusterCheckinInterval = 5000

/* Use the Oracle Quartz Driver to communicate via JDBC */
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.oracle.OracleDelegate
/* Have Quartz handle its own transactions with the database */
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX

/* Define the prefix for the Quartz tables in the database*/
org.quartz.jobStore.tablePrefix = QRTZ_
/* Tell Quartz it is clustered */
org.quartz.jobStore.isClustered = true
/* Tell Quartz that properties passed to the job call are
 * NOT all String objects */
org.quartz.jobStore.useProperties = false

/* Detect the jvm shutdown and call shutdown on the scheduler */
org.quartz.plugin.shutdownhook.class = org.quartz.plugins.management.ShutdownHookPlugin
org.quartz.plugin.shutdownhook.cleanShutdown = true

/* Log the history of triggers and jobs */
org.quartz.plugin.triggerHistory.class = org.quartz.plugins.history.LoggingTriggerHistoryPlugin
org.quartz.plugin.jobHistory.class = org.quartz.plugins.history.LoggingJobHistoryPlugin

Обратите внимание, что из указанных выше свойств вы можете установить org.quartz.plugins в настройке Log4j Config.groovy для регистрации соответствующего задания и запуска информации о запуске. Я думаю, что уровня info должно быть достаточно.

Редактировать или создать, scripts/_Events.groovy и добавьте следующее закрытие модификации войны: это исправляет известную ошибку плагина Quartz для установки правильного quartz.properties вместо пустого из плагина в окончательный файл войны.

eventCreateWarStart = { warName, stagingDir ->
    // Make sure we have the correct quartz.properties in the
    // correct place in the war to enable clustering
    ant.delete(dir:"${stagingDir}/WEB-INF/classes/quartz")
    ant.copy(file:"${basedir}/grails-app/conf/quartz/quartz.properties",
        todir:"${stagingDir}/WEB-INF/classes")
}

И все должно быть сделано ...

PS Если вы используете базу данных Oracle, добавьте следующее к BuildConfig.groovy в блоке зависимостей, чтобы иметь доступ к драйверам связи Quartz-Oracle:

runtime("org.quartz-scheduler:quartz-oracle:1.7.2") {
    // Exclude quartz as 1.7.3 is included from the plugin
    excludes('quartz')
}

PPS Файлы sql по ссылке выше - это просто SQL.Чтобы превратить его в файл гибернации, просто окружите каждую отдельную команду SQL узлом Hibernate database-object, например, так (снова с примером Oracle):

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
    '-//Hibernate/Hibernate Mapping DTD 3.0//EN'
    'http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd'>

<hibernate-mapping>

    <database-object>
        <create>
        CREATE TABLE QRTZ_JOB_DETAILS (
        JOB_NAME VARCHAR2(200) NOT NULL,
        JOB_GROUP VARCHAR2(200) NOT NULL,
        DESCRIPTION VARCHAR2(250) NULL,
        JOB_CLASS_NAME VARCHAR2(250) NOT NULL,
        IS_DURABLE VARCHAR2(1) NOT NULL,
        IS_VOLATILE VARCHAR2(1) NOT NULL,
        IS_STATEFUL VARCHAR2(1) NOT NULL,
        REQUESTS_RECOVERY VARCHAR2(1) NOT NULL,
        JOB_DATA BLOB NULL,
        PRIMARY KEY (JOB_NAME,JOB_GROUP)
        )
        </create>
        <drop>DROP TABLE QRTZ_JOB_DETAILS</drop>
        <dialect-scope name='org.hibernate.SomeOracleDialect' />
    </database-object>
...
    <database-object>
        <create>INSERT INTO QRTZ_LOCKS VALUES('TRIGGER_ACCESS')</create>
        <drop></drop>
        <dialect-scope name='org.hibernate.SomeOracleDialect' />
    </database-object>
...
</hibernate-mapping>

dialect-scope сообщает Hibernate, с которымДиалекты базы данных должны быть использованы для создания и удаления узлов.Вы можете попробовать опустить его и посмотреть, работает ли он, в противном случае вам, возможно, придется добавить диалект MySql, используемый вашим источником данных Grails.

0 голосов
/ 03 ноября 2015

Принятый ответ несколько устарел.Смотрите этот вопрос для более простого решения с более поздними версиями Grails: Использование источников данных grails в плагине кварца

...