Spring框架:连接JVM之间的桥梁

6

我有4台服务器,上面都安装了JVM。我编写了一个Java服务,Quartz定时每10分钟调用此服务。但是在这4个服务器上,每10分钟会进行4次调用。这种情况会导致竞争条件。我想在4个JVM上只运行一个服务。

使用Spring Framework该如何实现呢?

3个回答

3
这实际上很容易使用Quartz设置。Spring本身无法帮助您,因为它不知道正在运行的其他JVM。另一方面,Quartz具有集群调度程序的概念。 基本上,您需要设置一个所有4个JVM都可以共享的单个数据库。这将用作所有4个实例的调度程序。当计划任务时,只有一个实例使用集群调度程序运行该任务。 从Quartz网站集群的wiki中获取(http://www.opensymphony.com/quartz/wikidocs/ConfigJDBCJobStoreClustering.html),这是一个示例配置,说明如何设置集群调度程序。如果您以这种方式配置调度程序,则还可以直接从Spring设置这些属性。
#============================================================================
# Configure Main Scheduler Properties  
#============================================================================

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

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

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

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

org.quartz.jobStore.misfireThreshold = 60000

org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.oracle.OracleDelegate
org.quartz.jobStore.useProperties = false
org.quartz.jobStore.dataSource = myDS
org.quartz.jobStore.tablePrefix = QRTZ_

org.quartz.jobStore.isClustered = true
org.quartz.jobStore.clusterCheckinInterval = 20000

#============================================================================
# Configure Datasources  
#============================================================================

org.quartz.dataSource.myDS.driver = oracle.jdbc.driver.OracleDriver
org.quartz.dataSource.myDS.URL = jdbc:oracle:thin:@polarbear:1521:dev
org.quartz.dataSource.myDS.user = quartz
org.quartz.dataSource.myDS.password = quartz
org.quartz.dataSource.myDS.maxConnections = 5
org.quartz.dataSource.myDS.validationQuery=select 0 from dual

谢谢你,这对我很有帮助。我会尝试一下的。 - firstthumb

3
您的问题不是很清楚,让我看看我是否理解正确:您有4个服务器,每个服务器在虚拟机中运行Quartz,并且每个服务器都使用cron表达式安排相同的石英作业每10分钟运行一次。每10分钟,所有4个服务器都启动相同的作业,当它们都尝试在同一时间做同样的事情时,就会创建竞争条件。 这不是Spring的工作。然而,Quartz确实具有集群能力,您可以配置一个作业只在集群中的单个服务器上运行。它使用共享数据库来协调哪些服务器运行哪些作业,并确保它们不会全部同时执行。 文档在这里提供了一些信息:http://www.opensymphony.com/quartz/wikidocs/ConfigJDBCJobStoreClustering.html,但通常的opensymphony.com风格非常简洁和无用。

我通过skaffman的解释理解了这个问题。太棒了。为此点赞。 - peakit

0
在我们的Web应用程序中,我所做的是为每个作业包装一个类,在整个集群中获取全局锁(我使用memcached,因为我不太关心任务是否经常运行),并且仅在获得锁时运行该任务。当任务完成时,它可以释放锁(不要忘记在finally中执行此操作)。 将每个作业包装起来而不是更改调度程序的一个优点是,您可以有一些在所有计算机上运行的作业,而另一些则只在一个计算机上运行。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,