6

4 つのサーバーがあり、JVM がインストールされています。Quartz がこのサービスを 10 分ごとに呼び出す Java サービスを作成しました。しかし、4 つのサーバーでは、10 分ごとに 4 つの呼び出しが行われます。この状況により、競合状態が発生します。4 つの JVM で 1 つのサービスのみが必要です。

Spring Framework でそれを行うにはどうすればよいですか?

4

3 に答える 3

3

これは実際、Quartz で設定するのは非常に簡単です。Spring 自体は、実行中の他の JVM を認識していないため、ここではあまり役に立ちません。一方、Quartz にはクラスター化されたスケジューラーの概念があります。

基本的に、4 つの JVM すべてが共有できる単一のデータベースをセットアップする必要があります。これは、4 つのインスタンスすべてのスケジューラとして使用されます。ジョブがスケジュールされると、クラスタ化されたスケジューラを使用してインスタンスの 1 つだけによって実行されます。

クラスタリング用の Quartz Web サイト 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
于 2009-07-24T14:18:02.767 に答える
3

あなたの質問はあまり明確ではないので、私があなたを理解しているかどうかを確認させてください: 4 つのサーバーがあり、それぞれが VM 内で Quartz を実行しており、各サーバーには、cron 式を使用して 10 分ごとに実行するようにスケジュールされた同じ Quartz ジョブがあります。 . 10 分ごとに 4 つのサーバーすべてが同じジョブを開始し、すべてのサーバーが同時に同じことを実行しようとするため、競合状態が発生します。

これは本当にSpringの仕事ではありません。ただし、Quartz にはクラスタリング機能があり、クラスタ内の単一のサーバーのみを実行するようにジョブを構成します。共有データベースを使用して、どのサーバーがどのジョブを実行するかを調整し、すべてが一緒に実行されないようにします。

ドキュメントにはこれに関する情報がいくつかあります ここ、しかし通常のopensymphony.comスタイルでは、それらはかなりまばらで役に立ちません。

于 2009-07-24T14:08:17.413 に答える
0

私がWebアプリケーションで行うことは、各ジョブを、クラスター全体でグローバルロックを取得するクラスにラップし(タスクが頻繁に実行されるかどうかは気にしないため、memcachedを使用します)、実行するだけです。ロックを取得した場合のタスク。その後、タスクが完了するとロックを解除できます(でこれを行うことを忘れないでくださいfinally)。

スケジューラーを変更するのではなく、各ジョブをラップすることの利点の1つは、すべてのマシンで実行されるジョブと、1つだけで実行されるジョブを使用できることです。

于 2009-11-04T14:13:33.453 に答える