发布于 2024-12-05 10:32:40 字数 574 浏览 0 评论 0原文

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

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

TIA。

I am using the quartz plugin with Grails 1.3.7. I have a need to load balance/cluster a server app that uses quartz jobs. Apparently this is supported but I am finding that all the google search results and links within documents are broken. I've found some raw Java examples but I would assume Grails has a more grailsy way to do this. All I need is a simple example to use as a template. I understand I need to somehow enable quartz to use JDBC to store the jobs and manage locking.

I think a link to a single sample would do it. But literally every time I've found something that looks promising it points to a broken link on terracotta's site. Pretty much every site eventually leads me here: http://www.opensymphony.com/quartz/wikidocs/TutorialLesson9.html but when I look on terracotta's site I see Java stuff but no grails. If Java is the only way to do this then so be it, but I feel like there has to be some grails expertise on this out there somewhere!

TIA.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

划一舟意中人 2024-12-12 10:32:40

要在 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 表。 code>,如果它们在之前的运行中尚不存在。

创建一个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 code> 在 Config.groovy 的 Log4j 设置中记录相关作业和触发器触发信息。我认为 info 级别应该足够了。

编辑或创建 scripts/_Events.groovy 并添加以下 war 修改闭包。这修复了一个已知的 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")
}

您应该完成了...

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。要将其放入 Hibernate 文件中,只需用 Hibernate database-object 节点包围每个单独的 SQL 命令,如下所示(再次使用 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 数据源使用的 MySql 方言。

To cluster the Quartz plugin in Grails, there are some files you need to include in your project. First, install the grails-app/conf/QuartzConfig.groovy and make sure jdbcStore is enabled.

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

Next, install the Hibernate configuration files relevant to the database to which you will be connecting. For example, with Oracle, the base Hibernate xml config at grails-app/conf/hibernate/hibernate.cfg.xml is:

<?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>

The actual Quartz-Hibernate SQL file for this example will be named Quartz.oracle.hbm.xml and will reside in the same directory. These files should be available at the Quartz plugin on GitHub (https://github.com/nebolsin/grails-quartz), under src/templates/sql. Note, that these scripts only seem to work for DataSource create and create-drop, so you'll need to manually create the Quartz tables on an update, if they don't already exist from a previous run.

Create a grails-app/conf/quartz/quartz.properties file, and edit is to fit your business needs:

/* 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

Note from the above properties, you can set org.quartz.plugins in the Log4j setup of Config.groovy to log relevant job and trigger triggering information. I think info level should suffice.

Edit, or create, scripts/_Events.groovy and add the following war modification closure. This fixes a known Quartz plugin bug to install the correct quartz.properties, instead of a blank one from the plugin, in to the final war file.

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

And you should be done...

P.S. If you are using an Oracle database, add the following to BuildConfig.groovy in the dependencies block, so that you have access to the Quartz-Oracle communication drivers:

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 The sql files at the link above are just the SQL. To make it in to a hibernate file, just surround each individual SQL command with a Hibernate database-object node, like so (again w/ Oracle example):

<?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>

The dialect-scope tells Hibernate with which Database dialects the create and drop nodes should be used. You can try leaving it out and see if it works, otherwise you may have to add the MySql dialect used by your Grails DataSource.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文