現状
今作っているアプリは SpringBootのスケジュール機能で バッチ処理を実行している。
(別に作ると面倒だったので...)
問題
kubernetesで負荷分散のために複数Podで動かすとそれぞれでスケジュール機能が動いてしまう。
スケジュール機能は1台だけで動かしたい。
普通はバッチとして別にするのだろうけど、このままでできないかなと考えた結果
、
API機能とスケジュール機能をそれぞれをコンテナで動かせばいいのではと考えた。
必要な仕組み
ただ、以下のような仕組みがないとできない
スケジュール機能として動かす場合
スケジュール機能は有効にする 環境変数が設定されていない or 有効に設定できるようにするテスト実行時
スケジュール機能は無効にする テスト実行時は環境変数を毎回設定は面倒
テスト用プロパティファイルで無効にできるようにする。
結果
いろいろと調べながら実装した結果、
以下のようにすることで実現できた。
環境変数とプロパティファイルでスケジュール機能をOFFにするには @ConditionalOnPropertyのアノテーションを使えばいいことがわかった。
SchedulerConfig.kts
@Configuration @EnableScheduling @ConditionalOnProperty(prefix = "scheduling", name= arrayOf("enabled"), havingValue="true", matchIfMissing = true) class SchedulerConfig { // #1 }
もともと、@EnableSchedulingはApplicationクラスに設定していたが、 そのままだと@SpringBootApplicationも無効になってしまうため、 別途Configクラスを作成し設定した。
環境変数は、変数名はSCHEDULING_ENABLEDで指定できる。
javaの場合、変換ルールがあるらしく、分かりづらいが以下のようになる
環境変数 → javaプログラム中で指定するプロパティ SCHEDULING_ENABLED → scheduleing.enabled
テスト実行時は、テストクラスに
@ActiveProfiles("test")を指定しており、
application-test.propertiesが読み込まれる。
プロパティにスケジュール機能を無効設定を追加
application-test.properties
# スケジュール機能は無効 scheduling.enabled=false
テスト実行した結果
環境変数SCHEDULING_ENABLEDを設定せず、アプリケーションを起動
→ スケジュール機能は有効 →OK環境変数SCHEDULING_ENABLED=falseで、アプリケーションを起動
→ スケジュール機能は無効 →OKテスト実行時
→ スケジュール機能は無効 →OK
となってちゃんとできた。