2009-07-24 10 views
5

私は4台のサーバーを持ち、JVMがインストールされています。 Quartzがこのサービスを10分ごとに呼び出すJavaサービスを作成しました。しかし、4台のサーバーでは、10分ごとに4回の通話が行われます。このsitiuationは競合状態を作ります。私は4つのJVMで1つのサービスしか必要としません。Spring Framework JVMを互いに接続する

Spring Frameworkでどうすればいいですか?

答えて

3

これは、実際にはQuartzでセットアップするのはかなり簡単です。 Spring自体は、実行中の他のJVMを認識していないので、ここではあまり役に立ちません。一方、クォーツはクラスタースケジューラーという概念を持っています。

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

クラスタリング用のQuartz Webサイトwiki( http://www.opensymphony.com/quartz/wikidocs/ConfigJDBCJobStoreClustering.html)から、これはクラスタースケジューラーの設定方法の設定例です。スケジューラをそのように設定している場合は、春からこれらのプロパティを直接設定することもできます。各ジョブは、クラスタ全体でグローバルロックを取り出しクラスにラップされるため、タスクが実行されます場合

#============================================================================ 
# 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 
+0

ありがとうございます。これは私のために役立つでしょう。やってみます。 – firstthumb

3

私はあなたが理解しているかどうかを知りたいと思っています.4台のサーバがあり、それぞれがQuartzをVM内で実行していて、各サーバは10分ごとに実行されるようにスケジュールされ、 cron式を使用します。 10分ごとに、4つのサーバーすべてが同じ仕事を開始し、同じ時間に同じことをしようとする競合状態を作り出します。

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

ドキュメントにはこのhereに関する情報がありますが、通常のopensymphony.comスタイルではあまり散見されていません。

+0

私はあなたの説明skaffmanで質問を理解しました。驚くばかり。これは+1です。 – peakit

0

私は当社のウェブアプリケーションでやっていることは、私は本当に気にしないよう(私は、memcachedのを使用していますあまりにも頻繁に)、ロックがあればタスクを実行します。その後、タスクが完了したらロックを解除できます(finallyでこれを行うことを忘れないでください)。

スケジューラを変更するのではなく、各ジョブをラッピングする利点の1つは、すべてのマシンで実行されるジョブと、1つのジョブのみで実行されるジョブを持つことができることです。