【问题标题】:Grails clustering quartz jobs sample code and config desiredGrails 集群石英作业示例代码和所需配置
【发布时间】:2015-11-03 18:01:46
【问题描述】:

我正在使用带有 Grails 1.3.7 的石英插件。我需要对使用石英作业的服务器应用程序进行负载平衡/集群。显然这是支持的,但我发现文档中的所有谷歌搜索结果和链接都已损坏。我找到了一些原始的 Java 示例,但我认为 Grails 有一种更优雅的方式来做到这一点。我只需要一个简单的例子来用作模板。我知道我需要以某种方式启用quartz 以使用JDBC 来存储作业和管理锁定。

我认为链接到单个样本就可以了。但实际上,每次我发现一些看起来很有希望的东西时,它都会指向 terracotta 网站上的断开链接。几乎每个站点最终都将我带到这里:http://www.opensymphony.com/quartz/wikidocs/TutorialLesson9.html 但是当我查看 terracotta 的站点时,我看到了 Java 的东西,但没有 grails。如果 Java 是唯一的方法,那就这样吧,但我觉得在某个地方必须有一些 grails 专业知识!

TIA。

【问题讨论】:

    标签: grails cluster-computing quartz-scheduler


    【解决方案1】:

    要在 Grails 中集群 Quartz 插件,您需要在项目中包含一些文件。首先,安装grails-app/conf/QuartzConfig.groovy 并确保jdbcStore 已启用。

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

    接下来,安装与您要连接的数据库相关的 Hibernate 配置文件。例如,对于 Oracle,grails-app/conf/hibernate/hibernate.cfg.xml 的基本 Hibernate 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,并将驻留在同一目录中。这些文件应该可以在 GitHub 上的 Quartz 插件 (https://github.com/nebolsin/grails-quartz) 的 src/templates/sql 下找到。请注意,这些脚本似乎只适用于 DataSource createcreate-drop,因此您需要在 update 上手动创建 Quartz 表,如果它们在之前的运行中不存在。

    创建一个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
    

    注意以上属性,可以在Config.groovy的Log4j设置中设置org.quartz.plugins来记录相关作业和触发触发信息。我认为info 级别应该足够了。

    编辑或创建scripts/_Events.groovy 并添加以下战争修改闭包。这修复了一个已知的 Quartz 插件错误,将正确的 quartz.properties 安装到最终的 war 文件中,而不是插件中的空白。

    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")
    }
    

    你应该完成了......

    附:如果您使用的是 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')
    }
    

    P.P.S 上面链接中的 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 应该使用哪些数据库方言创建和删除节点。您可以尝试不使用它,看看它是否有效,否则您可能需要添加 Grails DataSource 使用的 MySql 方言。

    【讨论】:

    • 非常感谢您的详细回复。这看起来正是我正在寻找的信息。我使用 Amazon 的 RDS 作为 MySQL 的数据库。再次感谢。
    • 我一直找不到名为 Quartz.mysql.innodb.hbm.xml 的文件。我找到了 tables_mysql_innodb.sql,但在上面的示例 xml 代码中它暗示我应该设置
    • 我一直找不到名为 Quartz.mysql.innodb.hbm.xml 的文件。我找到了 tables_mysql_innodb.sql,但在上面的示例 xml 代码中它暗示我应该设置 。我已经搜索了从 github 签出的所有代码,并且没有这样的 xml 文件。我很抱歉,但我对这一切都很陌生。我的数据库是使用 InnoDB 的 Amazon 的 RDS MySQL。我想我必须更深入地了解 Quartz 和 Hibernate 配置才能理解这一点。我已经度过了漫长的一天,也许当我早上看到这一切时,它会更有意义!谢谢
    • 哎呀。没有仔细看,看不到它们只是 SQL。您可以轻松地将其修改为 hbm 文件。我已经编辑了答案以包含一些关于转换为 hbm 文件的说明。
    • 我认为您可以将属性文件添加为配置位置,而不是篡改脚本/_Events.groovy:grails.config.locations = [ "classpath:conf/quartz/quartz.properties" ]
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-28
    相关资源
    最近更新 更多