Grails集群石英工作示例代码和配置需要 [英] Grails clustering quartz jobs sample code and config desired

查看:99
本文介绍了Grails集群石英工作示例代码和配置需要的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



我认为链接到单个样本就可以做到。但从字面上看,每次我找到看起来很有希望的东西时,都会指向兵马俑网站上的一个断开的链接。几乎每个网站最终都会将我带到这里: http://www.opensymphony.com/quartz/ wikidocs / TutorialLesson9.html ,但是当我看到兵马俑的网站时,我会看到Java的东西,但没有Grails。如果Java是唯一能够做到这一点的方法,那就这么做吧,但是我觉得在这方面必须有一些Grails专业知识!

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

 石英{
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配置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 create create-drop ,因此您需要手动在 update 上创建Quartz表(如果它们不存在于上一次运行中)。



创建一个Quartz表 grails-app / conf / quartz / quartz.properties 文件和编辑符合您的业务需求:

 / *为
*群集中的所有调度程序自动生成调度程序ID * /
org.quartz.scheduler.instanceId = AUTO
/ * Don不要让QuartzPhone Home查看是否有新版本
* * /
org.quartz.scheduler.skipUpdateCheck = true

org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
/ *仅为一个线程配置Quartz,因为唯一的作业
*应该每天运行一次* /
org.quartz.threadPool.threadCount = 4
/ *给线程一个Thread.MIN_PRIORITY级别* /
org.quartz.threadPool.threadPriority = 1

/ *允许一分钟(60,000毫秒)的非点火在
*之前通过触发器称为失火* /
org.quartz.jobStore.misfireThreshold = 60000
/ *仅处理2个失火触发器* /
org.quartz.jobStore.maxMisfiresToHandleAtATime = 2
/ *每5000毫秒检查一次群集* /
org.quartz.jobStore.clusterCheckinInterval = 5000

/ *使用Oracle Quartz Driver通过JDBC进行通信* /
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.oracle.OracleDelegate
/ *使用Quartz处理它自己的数据库事务* /
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX

/ *定义数据库中Quartz表的前缀* /
org.quartz.jobStore.tablePrefix = QRTZ_
/ *告诉Quartz它被聚集* /
org.quartz.jobStore.isClustered = true
/ *告诉Quartz该属性传递给作业调用的是
*不是所有String对象* /
org.quartz.jobStore.useProperti es = false

/ *检测调度器上的jvm shutdown和调用关闭* /
org.quartz.plugin.shutdownhook.class = org.quartz.plugins.management.ShutdownHookPlugin
org.quartz.plugin.shutdownhook.cleanShutdown = true

/ *记录触发器和作业的历史记录* /
org.quartz.plugin.triggerHistory.class = org.quartz。 plugins.history.LoggingTriggerHistoryPlugin
org.quartz.plugin.jobHistory.class = org.quartz.plugins.history.LoggingJobHistoryPlugin

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



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

  eventCreateWarStart = {warName,stagingDir  - > 
//确保我们在
中有正确的quartz.properties //在战争中的正确位置启用集群
ant.delete(dir:$ {stagingDir} / WEB-INF / classes / quartz)
ant.copy(文件:$ {basedir} /grails-app/conf/quartz/quartz.properties,
todir:$ {stagingDir} / WEB-INF / classes)
}

你应该完成...



PS如果您使用的是Oracle数据库,请在依赖关系块中将以下内容添加到 BuildConfig.groovy 中,以便您可以访问Quartz-Oracle通信驱动程序:

(org.quartz-scheduler:quartz-oracle:1.7.2){
//排除石英为1.7。 3包含在插件中
excludes('quartz')
}






PPS上面链接中的sql文件只是SQL。要使它进入一个hibernate文件,只需用Hibernate database-object 节点包围每个单独的SQL命令,就像这样(再次使用Oracle示例):

 <?xml version ='1.0'encoding ='UTF-8'?> 
<!DOCTYPE hibernate-mapping PUBLIC
' - // Hibernate / Hibernate映射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,
描述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>

方言范围数据库方言应该使用创建和删除节点。您可以尝试将其保留并查看它是否有效,否则可能需要添加Grails数据源使用的MySql方言。


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.

解决方案

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.

这篇关于Grails集群石英工作示例代码和配置需要的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆