1
1

More than 1 year has passed since last update.

EventBridgeによる重複起動を防ぐ(Spring Batch)

Posted at

背景

JOBスケジューラー(オンプレ)から RESTAPI (SpringBoot) 経由でバッチを起動している。
オンプレからAWSへの移行に伴い、JOBスケジューラー(オンプレ)から Amazon EventBridge Scheduler へ移行したい。
負荷分散のため、バッチの起動は RESTAPI から ECS タスクによる起動(SpringBatch)に変更する。

課題

EventBridge には 以下の仕様が存在します。

まれに、単一のイベントまたはスケジュールされた期間に対して同じルールが複数回実行されたり、トリガーされる特定のルールに対して同じターゲットを複数回呼び出されたりする場合があります。

つまり、EventBridge Rules/Scheduler は ECS タスクを稀に重複実行します。😨
Scheduler には重複実行の確率を下げる仕組み ( フレックスタイムウィンドウ ) が存在しますが、0 % にはならないようなのでアプリケーション側で対処する必要があります。

対処内容

eventbridge 重複起動 でググるといろいろな方法が出てきますが、SpringBatch の仕組みで対処しました。
SpringBatch の RunIdIncrementer は JOBを実行する度に run.id というJOBパラメータを +1 するので、何回も同じJOBを動かすことができます。
しかし、何回も同じJOBを動かせてしまうと EventBridge の重複実行は防げません。
そこで、以下のような MonthlyIncrementer を作りました。これを RunIdIncrementer の代わりに設定します。

public class MonthlyIncrementer implements JobParametersIncrementer {
    @Override
    public JobParameters getNext(@Nullable JobParameters previousParameters) {
        JobParameters jobParameters = Optional.ofNullable(previousParameters).orElse(new JobParameters());
        YearMonth now = YearMonth.from(LocalDateTime.now());

        return new JobParametersBuilder(jobParameters)
                .addString("run.monthly.id", now.toString())
                .toJobParameters();
    }
}

これにより、月をまたがない限り JOB パラメータが変わらなくなり重複実行を防ぐことができます。
日次バッチの場合もほぼ同様です。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1