Java 连接JVM的Spring框架

Java 连接JVM的Spring框架,java,spring,quartz-scheduler,cluster-computing,Java,Spring,Quartz Scheduler,Cluster Computing,我有4台服务器,上面安装了JVM。我编写了一个java服务,Quartz每10分钟调用一次这个服务。但在4台服务器中,每10分钟会进行4次呼叫。这种定位创造了竞争条件。我只想要4个JVM上的一个服务 我如何使用Spring Framework做到这一点?您的问题不是很清楚,所以让我看看我是否理解您:您有4台服务器,每台服务器在VM中运行Quartz,每台服务器都有相同的Quartz作业,计划每10分钟运行一次,使用cron表达式。每10分钟,所有4台服务器都会启动同一个作业,在它们同时尝试做相同

我有4台服务器,上面安装了JVM。我编写了一个java服务,Quartz每10分钟调用一次这个服务。但在4台服务器中,每10分钟会进行4次呼叫。这种定位创造了竞争条件。我只想要4个JVM上的一个服务


我如何使用Spring Framework做到这一点?

您的问题不是很清楚,所以让我看看我是否理解您:您有4台服务器,每台服务器在VM中运行Quartz,每台服务器都有相同的Quartz作业,计划每10分钟运行一次,使用cron表达式。每10分钟,所有4台服务器都会启动同一个作业,在它们同时尝试做相同的事情时创建竞争条件

这不是春天的工作。但是,Quartz具有群集功能,您可以将作业配置为仅在群集中运行一台服务器。它使用一个共享数据库来协调哪些服务器运行哪个作业,并确保它们不会一起执行


文档中有一些关于这方面的信息,但在通常的opensymphony.com样式中,它们非常稀疏且没有帮助。

这实际上很容易用Quartz设置。Spring本身在这里帮不了你多少忙,因为它不知道其他正在运行的JVM。另一方面,Quartz具有集群调度程序的概念

基本上,您需要建立一个所有4个JVM都可以共享的数据库。这将用作所有4个实例的计划程序。在调度作业时,使用群集调度程序仅由一个实例运行该作业

取自Quartz网站wiki,用于聚类( ),这是一个关于如何设置群集调度程序的示例配置。如果以这种方式配置调度程序,也可以直接从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

在我们的web应用程序中,我所做的是将每个作业包装在一个类中,该类在整个集群中取出一个全局锁(我使用memcached,因为我并不真正关心任务是否经常运行),并且仅在任务获得锁时才运行任务。然后,它可以在任务完成时释放锁(不要忘记在
finally
中执行此操作)


包装每个作业而不是更改计划程序的一个优点是,您可以有一些作业在所有机器上运行,而有些作业只在一台机器上运行。

谢谢。这将对我有帮助。我会试试的。我理解了你的解释,斯考夫曼。太棒了+这是我的荣幸。