我有4台服务器并且安装了JVM。我写了一个java服务,Quartz每隔10分钟调用一次这个服务。但在4台服务器中,每10分钟完成4次呼叫。这种情绪会造成竞争状态。我只想要4个JVM上的一个服务。
我如何使用Spring Framework做到这一点?
答案 0 :(得分:3)
你的问题不是很清楚,所以让我看看我是否理解你:你有4个服务器,每个服务器在一个虚拟机内部运行Quartz,每个服务器都有相同的石英作业,计划每10分钟运行一次,使用一个cron表达。每隔10分钟,所有4台服务器都会开始相同的工作,创造竞争条件,因为他们都试图同时做同样的事情。
对于Spring来说,这不是一个真正的工作。但是,Quartz确实具有群集功能,您可以将作业配置为仅在群集中运行单个服务器。它使用共享数据库来协调哪些服务器运行哪个作业,并确保它们不是全部一起完成。
这些文档有关于here的一些信息,但在通常的opensymphony.com风格中,它们非常稀疏且无益。
答案 1 :(得分: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
答案 2 :(得分:0)
我在我们的Web应用程序中所做的是将每个作业包装在一个类中,该类在集群中取出全局锁(我使用memcached,因为我并不关心任务是否经常运行),并且只有在获得锁定时才运行任务。然后它可以在任务完成时释放锁定(不要忘记在finally
中执行此操作。)
包装每个作业而不是更改调度程序的一个优点是,您可以在所有计算机上运行一些作业,而在一台计算机上运行一些作业。