Related: Quartz Clustering - triggers duplicated when the server startsは、私はJavaベースのクラスタ環境でスケジュールされたジョブを管理するためにクォーツスケジューラを使用しているクラスタ環境
にクォーツトリガーの作成します。ある時点では、クラスタにはいくつかのノードがあり、すべてのノードが接続するpostgresqlデータベースのデータストアに基づいてQuartzを実行します。
インスタンスが初期化されると、それはジョブを作成または更新しようとすると、このコードを実行することにより、石英データストアにトリガ:
private void createOrUpdateJob(JobKey jobKey, Class<? extends org.quartz.Job> clazz, Trigger trigger) throws SchedulerException {
JobBuilder jobBuilder = JobBuilder.newJob(clazz).withIdentity(jobKey);
if (!scheduler.checkExists(jobKey)) {
// if the job doesn't already exist, we can create it, along with its trigger. this prevents us
// from creating multiple instances of the same job when running in a clustered environment
scheduler.scheduleJob(jobBuilder.build(), trigger);
log.error("SCHEDULED JOB WITH KEY " + jobKey.toString());
} else {
// if the job has exactly one trigger, we can just reschedule it, which allows us to update the schedule for
// that trigger.
List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
if (triggers.size() == 1) {
scheduler.rescheduleJob(triggers.get(0).getKey(), trigger);
return;
}
// if for some reason the job has multiple triggers, it's easiest to just delete and re-create the job,
// since we want to enforce a one-to-one relationship between jobs and triggers
scheduler.deleteJob(jobKey);
scheduler.scheduleJob(jobBuilder.build(), trigger);
}
}
このアプローチは、多くの問題を解決する:
- 環境が正しく構成されていない場合(つまり、ジョブ/トリガーが存在しない場合)は、起動する最初のインスタンスによって作成されます
- ジョブはすでに存在しますが、 bは7分ごとに実行され、5分ごとに実行されます)、新しいトリガーを定義することができ、再デプロイメントによってデータベース内のトリガーが再スケジュールされます。
- ジョブのインスタンスが1つだけ作成されます。ジョブ自体によって定義された指定されたJobKeyによって常にジョブを参照します。これは、クラスタ内のノード数や展開回数にかかわらず、ジョブ(および関連するトリガー)が正確に1回作成されることを意味します。
これはすべてうまくいいですが、2つのインスタンスがまったく同時に開始された場合の競合状態が懸念されます。このコードの周りには、クラスタ内のすべてのノードが尊重するグローバルロックが存在しないため、2つのインスタンスが同時にオンラインになると、重複するジョブやトリガが発生する可能性があります。
クラスタ環境でQuartzジョブとトリガを自動的に定義するベストプラクティスはありますか?または自分のロックを設定する必要がありますか?
これは、Quartzが同じ仕事のために複数のトリガーを作成するのを妨げないという意味で、私が探していたものではありませんが、それらのトリガーの1つだけが確実に実行されます。与えられたウィンドウ、私はそれが問題を解決すると思うので、ラウンドアバウトのような方法です。 – MusikPolice