Quartz 2.2 多调度器和@DisallowConcurrentExecution

Quartz 2.2 multi scheduler and @DisallowConcurrentExecution

请考虑这个例子。

示例 Web 应用程序在启动时调用 scheduler.start()。配置为将其作业存储在数据库中的调度程序。

该应用程序被复制到六个网络服务器上。

因此,如果我们启动六个网络服务器,我们将在一个数据库上有六个同名的调度程序。如https://quartz-scheduler.org/documentation/quartz-2.1.x/cookbook/MultipleSchedulers所述:

Never start (scheduler.start()) a non-clustered instance against the same set of database tables that any other instance with the same scheduler name is running (start()ed) against. You may get serious data corruption, and will definitely experience erratic behavior.

所以这会失败。

我的问题是,如果我确定我的所有作业都具有 @DisallowConcurrentExecution,那么上面的工作还是会失败?!


如果 @DisallowConcurrentExecution 没有帮助,我应该手动配置一台服务器作为一些 Master

public class StartUp implements ServletContextListener {

   public void contextInitialized(ServletContextEvent event) {
       if(THIS_IS_MASTER_TOMCAT){
         scheduler.start()
       }
}

还有更好的方法吗?!

基本上 Rene M. 是正确的。以下是与 Quartz 相关的文档:

http://www.quartz-scheduler.org/documentation/quartz-2.2.x/configuration/ConfigJDBCJobStoreClustering.html

现在介绍一些背景知识和我们在我公司使用的概念示例。我们在 Wildfly Cluster 中使用石英集群模式 。即每个 wildfly 集群节点 运行s quartz。由于 quartz 在集群模式下 运行ning 本身并且指向相同的数据库模式,我们保证每个 集群 运行 一个作业 。再次,请参阅文档。关键问题是:

  1. 单个石英集群必须 运行 针对单个石英数据库
    模式。您显然必须按每个创建关系数据库表 文档。没什么大不了的。
  2. 您必须设置 quartz.property 个文件 正确并且其中的每个节点都必须存在一个副本 簇。 完全相同的 quartz.property 文件
  3. 最后,您必须使用 NonJTA 数据源,否则 quartz 集群将失败。在 Wildfly 世界中,这通常意味着石英 将需要自己的 数据源。

quartz.property 示例:

    #============================================================================
# Configure Main Scheduler Properties 
#============================================================================

org.quartz.scheduler.instanceName = BjondScheduler
org.quartz.scheduler.instanceId = AUTO

#============================================================================
# Configure ThreadPool 
#============================================================================

org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 5

#============================================================================
# Configure JobStore 
#============================================================================

org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreCMT
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
org.quartz.jobStore.useProperties = false
org.quartz.jobStore.tablePrefix=QRTZ_
org.quartz.jobStore.isClustered = true
org.quartz.jobStore.clusterCheckinInterval = 5000

org.quartz.scheduler.wrapJobExecutionInUserTransaction = true
org.quartz.scheduler.userTransactionURL = java:jboss/UserTransaction

org.quartz.jobStore.dataSource = PostgreSQLDS
org.quartz.jobStore.nonManagedTXDataSource = PostgreSQLDSNoJTA

org.quartz.dataSource.PostgreSQLDSNoJTA.jndiURL=java:jboss/datasources/PostgreSQLDSNoJTA
org.quartz.dataSource.PostgreSQLDS.jndiURL=java:jboss/datasources/PostgreSQLDS


#============================================================================
# Configure Logging
#============================================================================
#org.quartz.plugin.jobHistory.class=org.quartz.plugins.history.LoggingJobHistoryPlugin
#org.quartz.plugin.jobHistory.jobToBeFiredMessage=Bjond Job [{1}.{0}] to be fired by trigger [{4}.{3}] at: {2, date, HH:mm:ss MM/dd/yyyy} re-fire count: {7}
#org.quartz.plugin.jobHistory.jobSuccessMessage=Bjond Job [{1}.{0}] execution complete and reports: {8}
#org.quartz.plugin.jobHistory.jobFailedMessage=Bjond Job [{1}.{0}] execution failed with exception: {8}
#org.quartz.plugin.jobHistory.jobWasVetoedMessage=Bjond Job [{1}.{0}] was vetoed. It was to be fired by trigger [{4}.{3}] at: {2, date, dd-MM-yyyy HH:mm:ss.SSS}

现在我们的数据源片段在 standalone.xml 中:

            <datasource jta="false" jndi-name="java:jboss/datasources/PostgreSQLDSNoJTA" pool-name="PostgreSQLDSNoJTA" enabled="true" use-java-context="true" use-ccm="true">

您根据需要填写此数据源元素的其余部分。 @DisallowConcurrentExecution 是防止单个节点上的多个作业执行特定方法的好主意,但正是石英集群阻止了多个 VM 上的相同作业 运行ning;不是这个注释。