Skip to content

mysd33/sample-batch-jobflow

Repository files navigation

SpringBootのジョブフローの純バッチアプリケーションサンプル

Warning

現在、サンプルAPを作成中です。

概要

  • Spring BootでAWS Step Functionsを使って、ステートマシンをジョブの実行順序を管理するジョブフローとして実行する、バッチのサンプルAPである。

  • アプリケーションは、Spring Batchを使用しており、コマンドライン引数で指定されたジョブIDとジョブの入力データをもとに、ジョブを実行するようになっている。

  • Step Functionsのステートマシンからジョブの実行順序制御(実行順序制御するフローを「ジョブフロー」と呼ぶことにする)を行う。

  • ステートマシンから各ステートでAWS Batchを起動しコマンド引数で指定されたジョブIDとパラメータのジョブを実行するようになっている。

  • Step FunctionsのタスクトークンとAPIを利用して、ジョブの処理結果を、後続のフローおよびジョブの入力として引き渡せる仕組みも用意している。

    コマンド実行

    ジョブフロー

  • 本サンプルAPのソフトウェアアーキテクチャの図は以下の通り。

ソフトウェアアーキテクチャ(タスクレット)

ソフトウェアアーキテクチャ(チャンク)

プロジェクト構成

  • sample-batch-flow
    • 本プロジェクト。Spring Bootのバッチアプリケーションで、Step Functionsを介してジョブを処理することが可能である。
      • デフォルトでは「spring.profiles.active」プロパティが「dev」になっている。プロファイルdevの場合は、RDB永続化にはH2DBによる組み込みDBになっている。
      • プロファイルproductionの場合は、RDB永続化にはPostgreSQL(AWS上はAurora等)になっている。

事前準備

動作手順

  • Step Functionsを使ったAWS上での動作確認は、こちらのCloudFormationのサンプルテンプレートを利用して、AWS上にAPをデプロイし、Step Functionsのステートマシンからジョブフローを実行することで可能である。

  • ローカル上でのAP動作は、ジョブごとでの実行のみが可能である。

Warning

現在、執筆中

PostgreSQLのローカル起動

  • Profileが「dev」でSpringBootアプリケーションを実行する場合、H2DBが起動するので、何もしなくてよい。
  • Profileが「production」に切り替えてSpringBootアプリケーションを実行する場合、DBがPostgreSQLで動作する設定になっているため、事前にPostgreSQLを起動する必要がある。
    • AWS上でAPを起動する場合はAurora for PostgreSQLや、RDS for PostgreSQLを起動しておくことを想定している。
  • Profile「procution」でAPをローカル実行する場合は、AP起動前にあらかじめ、PostgreSQLをDockerで起動しローカル実行しておく必要がある。以下で、PostgreSQLのローカル実行手順を示す。
#Postgres SQLの起動
docker run --name test-postgres -p 5432:5432 -e POSTGRES_PASSWORD=password -d postgres
#Postgresのコンテナにシェルで入って、psqlコマンドで接続
docker exec -i -t test-postgres /bin/bash
> psql -U postgres

# psqlで、testdbデータベースを作成
postgres> CREATE DATABASE testdb;

S3の設定

  • Profileが「dev」でSpringBootアプリケーションを実行する場合、S3アクセスは無効化し、ローカルのファイルシステムアクセスする設定になっている。
    • application-dev.ymlの「example.s3.localfake.type」が「file」であり、「example.s3.localfake.base-dir」を一時保存するファイルシステムのディレクトリパスが現状、C:\tmpになっているので、フォルダの変更が必要な場合は、変更する。
      • 「sample-bff」アプリケーション側も変更が必要

Note

MinIOのOSSのGitHubはアーカイブされて、以前のOSSのDockerイメージの配布を停止してしまった模様。現在は、MinIOは、AIStor Serverとして、Free版とEnterprise版の2つのエディションで提供されている。 以下のダウンロードサイトの手順にしたがって、MinIOのexeをダウンロードして、ローカルでMinIOを起動することが可能である。Free版はMinIO AIStor Free Tier License Agreementに同意することで利用可能となっており、スタンドアロンモードのみでの利用、開発作業、プロトタイピング、研究等の目的での利用に制限されている。なお、Free版でもライセンスキーの取得が必要である。 なお、以前のバージョンをまだ使用している場合、OSSライセンスと商用ライセンスのデュアルライセンスで提供されており、OSSライセンスはGNU AGPL v3であったためMinIOを同梱しての配布、利用等には注意すること。

Note

LocalStackの無料版では、CIクレジット(CI環境での実行)は含まれていないため、利用には注意すること。
また、LocalStackの今後の展望では、Community版とPro版を1つのDockerイメージに統合することや、無料版であっても、アカウント登録が必要になることがアナウンスされているため、今後の動向に注意すること。

Note

s3rverは、現在、アーカイブされているので、利用等には注意すること。

  • Profileが「dev」でも、S3のローカル起動用のFake(MinIO、LocalStack、s3rver)を起動したい場合には、以下の通り

    • MinIOの場合

      • MinIOのダウンロードサイトの手順にしたがってコマンドを実行しminio.exeをダウンロードする。

      • [REQUEST TRIAL LICENSE]のボタンをクリックし、必要事項を記入しライセンスキーを取得する。(メールアドレス宛にライセンスキーのメールが届くので、メール内のリンクをクリックしてライセンキーを確認する)

      • 取得したライセンスキーを、minio.licenseというファイル名で保存する

      • 以下は、Windows版での起動例

        • C:\minioフォルダにminio.exe、minio.licenseを格納して、起動した例(デフォルトポート9000番ポートで起動、コンソールは9001番ポートで起動するので適宜変更すること)
        C:\minio\minio.exe server C:\minio\data --license C:\minio\minio.license --address ":9000" --console-address ":9001"
      • application-dev.ymlの「example.s3.localfake.type」を「minio」に変更し、以下の通り設定

        example:
          s3:
            localfake:
              type: minio
              port: 9000
              access-key-id: minioadmin
              secret-access-key: minioadmin
            bucket: mysd33bucket123
    • LocalStackの場合

      • Docker起動が前提になるため、Dockerがインストールされている必要がある。

      • LocalStackのサイトに記載された、いずれかの手順に従いインストールし、LocalStackを起動

        • ここではDocker Composeでの起動例を記載する。すでに、サンプルとしてlocalstackフォルダにdocker-compose.ymlが用意されているので、以下の通り起動する。
        cd localstack
        docker compose up -d
        $ aws configure --profile localstack
        AWS Access Key ID [None]: dummy
        AWS Secret Access Key [None]: dummy
        Default region name [None]: ap-northeast-1
        Default output format [None]: json
        • バケット作成
          • サンプルAPが起動時のにアクセスするS3のバケットを作成してくれるので通常は作成不要。
          • 明示的に作成する場合は、LocalStackが起動したら、AWS CLIでS3のバケットを作成する。
        aws s3 mb --endpoint-url=http://localhost:4566 --profile localstack s3://mysd33bucket123
        aws s3 ls --endpoint-url=http://localhost:4566 --profile localstack
        • バケット内のファイルの確認(サンプルAP実行後に使用)
        aws s3 ls --endpoint-url=http://localhost:4566 --profile localstack s3://mysd33bucket123 --recursive
    • s3rverの場合

      • s3rverのサイトの手順に従い、npmでインストールし、s3rverを起動

      • 以下、起動例

        s3rver -d C:\s3rver
        
      • application-dev.ymlの「example.s3.localfake.type」を「s3rver」に変更し、以下の通り設定

        example:
          s3:
            localfake:
              type: s3rver
              port: 4568
            bucket: mysd33bucket123
  • Profileが「production」に切り替えてSpringBootアプリケーションを実行する場合、S3を使用する設定になっているため、事前にAWS上に、S3のバケットを作成する必要がある。

    • application-production.ymlの「aws.s3.bucket」プロパティを作成したバケット名に変更する。
    • APがS3にアクセスする権限が必要なので、開発端末上でローカル実行する場合はS3のアクセス権限をもったIAMユーザのクレデンシャル情報が「%USERPROFILE%/.aws/credentials」や「~/.aws/credentials」に格納されている、もしくはEC2やECS等のAWS上のラインタイム環境で実行する場合は対象のAWSリソースにSQSのアクセス権限を持ったIAMロールが付与されている必要がある。

Dockerでのアプリ起動

  • Mavenビルド
#Windows
.\mvnw.cmd package
#Linux/Mac
./mvnw package
  • ローカルでDockerビルド
docker build -t XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/sample-batch-jobflow:latest .
  • ローカルでDocker実行(Profileを「dev」でSpringBoot実行)
# job901を実行する例。引数で、ジョブID、ジョブの入力データ、タスクトークンを渡す例。
docker run --name samplebatch-jobflow --env SPRING_PROFILES_ACTIVE=dev,log_default --env TASK_TOKEN=dummy XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/sample-batch-jobflow:latest --spring.batch.job.name=job901 inputData=input901
# job902を実行する例。引数で、ジョブID、ジョブの入力データ、タスクトークンを渡す例。
docker run --name samplebatch-jobflow --env SPRING_PROFILES_ACTIVE=dev,log_default --env TASK_TOKEN=dummy XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/sample-batch-jobflow:latest --spring.batch.job.name=job902 inputData="{\"result\":\"result_job901\"}" taskToken=dummy

#logをjson形式に変更する場合
docker run --name samplebatch-jobflow --env SPRING_PROFILES_ACTIVE=dev,log_container --env TASK_TOKEN=dummy XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/sample-batch-jobflow:latest
--spring.batch.job.name=job901 inputData=input901
  • ローカルでDocker実行(Profileを「production」でSpringBoot実行) 
    • ※PostgreSQLのローカル起動も必要
docker run -v %USERPROFILE%\.aws\:/home/app/.aws/ --name samplebatch-jobflow --env SPRING_PROFILES_ACTIVE=production,log_default --env TASK_TOKEN=dummy --env SPRING_DATASOURCE_URL=jdbc:postgresql://host.docker.internal:5432/testdb XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/sample-batch-jobflow:latest --spring.batch.job.name=job901 inputData=input901


#logをjson形式に変更する場合
docker run -v %USERPROFILE%\.aws\:/home/app/.aws/ --name samplebatch-jobflow --env SPRING_PROFILES_ACTIVE=production,log_container --env TASK_TOKEN=dummy --env SPRING_DATASOURCE_URL=jdbc:postgresql://host.docker.internal:5432/testdb XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/sample-batch-jobflow:latest --spring.batch.job.name=job901 inputData=input901
  • ECRプッシュ
aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com
docker push XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/sample-batch-jobflow:latest

ソフトウェアフレームワーク

  • 本サンプルアプリケーションでは、ソフトウェアフレームワーク実装例も同梱している。簡単のため、アプリケーションと同じプロジェクトでソース管理している。
  • ソースコードはcom.example.fwパッケージ配下に格納されている。
    • 本格的な開発を実施する場合には、業務アプリケーションと別のGitリポジトリとして管理し、CodeArtifactやSonatype NEXUSといったライブラリリポジトリサーバでjarを管理し、pom.xmlから参照するようにすべきであるし、テストやCI/CD等もちゃんとすべきであるが、ここでは、あえて同じプロジェクトに格納してノウハウを簡単に参考にしてもらいやすいようにしている。
  • 各機能と実現方式は、以下の通り。
分類 機能 機能概要と実現方式 拡張実装 拡張実装の格納パッケージ
バッチ バッチAP実行制御 Spring BootおよびSpringBatchによりコマンドラインで指定された対象のジョブを起動する機能を提供する。また、SpringBatchに関する実行制御機能を提供する。 com.example.fw.batch.core
ジョブフロー実行支援 StepFunctionsによるジョブフロー実行の際に、パラメータの引き渡しや、後続ジョブへの実行結果の受け渡しを支援する機能を提供する。 com.example.fw.batch.jobflow
大量データアクセス SpringBatchのItemReader、ItemWriterを利用し、大容量のファイルやDBのレコードを逐次読み書きする機能を提供する。 - -
集約例外ハンドリング エラー(例外)発生時、SpringBatchの機能によりDBのロールバックするとともに、JobExecutionListenerを利用しエラーログの出力といった共通的なエラーハンドリングを実施する。 com.example.fw.batch.exeption
com.example.fw.batch.listener
トランザクション管理 Spring Frameworkのトランザクション管理機能を利用して、タスクレットやチャンクに対するトランザクション管理を実現する機能を提供する。 - -
オン・バッチ共通 RDBアクセス MyBatisやSpringとの統合機能を利用し、DBコネクション取得、SQLの実行等のRDBへのアクセスのため定型的な処理を実施し、ORマッピングやSQLマッピングと呼ばれるドメイン層とインフラ層のインピーダンスミスマッチを吸収する機能を提供する。 - -
HTTPクライアント WebClientやRestTemplateを利用してREST APIの呼び出しやサーバエラー時の例外の取り扱いを制御する。 com.example.fw.common.httpclient
リトライ・サーキットブレーカ Spring Cloud Circuit Breaker(Resillience4j)を利用し、REST APIの呼び出しでの一時的な障害に対する遮断やフォールバック処理等を制御する。また、WebClientのリトライ機能でエクスポネンシャルバックオフによりリトライを実現する。なお、AWSリソースのAPI呼び出しは、AWS SDKにてエクスポネンシャルバックオフによりリトライ処理を提供。 - -
入力チェック Java BeanValidationとSpringのValidation機能を利用し、単項目チェックや相関項目チェックといった画面の入力項目に対する形式的なチェックを実施する。 com.example.fw.common.validation
メッセージ管理 MessageResourceで画面やログに出力するメッセージを管理する。 com.example.fw.common.message
例外 RuntimeExceptionを継承し、エラーコード(メッセージID)やメッセージを管理可能な共通的なビジネス例外、システム例外を提供する。 com.example.fw.common.exception
ロギング Slf4jとLogback、SpringBootのLogback拡張、ver3.4からのStructured Logs機能を利用し、プロファイルによって動作環境に応じたログレベルや出力先(ファイルや標準出力)、出力形式(タブ区切りやJSON)に切替可能とする。またメッセージIDをもとにログ出力可能な汎用的なAPIを提供する。 com.example.fw.common.logging
分散トレーシング(ログ) Micrometer Tracingを利用して、トレースIDやスパンIDをAP間でのREST API呼び出しで引継ぎ、ログにも記録することを実現する。 - -
分散トレーシング(X-Ray) X-Rayによるサービス間の分散トレーシング・可視化を実現する。バッチの場合は以下1パターンの実装のみを提供している。
・ADOT(AWS Distro for Open Telemetry)でAP側は未実装で自動計測する
-
メトリクス転送(CloudWatch) Spring Cloud for AWSの機能により、JVM等、Spring Boot Actuatorが提供するメトリクスをCloudWatchメトリクスへ転送する。カスタムメトリクスとしてMyBatisのSQLの実行状況に対応する。 - -
プロパティ管理 SpringBootのプロパティ管理を使用して、APから環境依存のパラメータを切り出し、プロファイルによって動作環境に応じたパラメータ値に置き換え可能とする。 - -
プロパティ管理(SSM、Secrets Manager) Spring Cloud for AWSの機能により、AWSのSSMパラメータストアやSecrets Managerに切り出したAPから環境依存のパラメータを、プロファイルによって動作環境に応じたパラメータ値に置き換え可能とする。 - -
オブジェクトマッピング MapStructを利用し、類似のプロパティを持つリソースオブジェクトやDTOとドメインオブジェクト間で、値のコピーやデータ変換処理を簡単にかつ高速に行えるようにする。 - -
DI Springを利用し、DI(依存性の注入)機能を提供する。 - -
AOP SpringとAspectJAOPを利用し、AOP機能を提供する。 - -
ボイラープレートコード排除 Lombokを利用し、オブジェクトのコンストラクタやGetter/Setter等のソースコードを自動生成し、ボイラープレートコードを排除する。 - -
S3 Local起動 開発端末での動作確認のため、APをローカル起動可能とするようファイルシステムアクセスに差し替えたFakeやS3互換のFakeのサーバ(LocalStack、MinIO、s3ver)に接続する機能を提供する。 com.example.fw.common.objectstorage
  • 以下は、今後追加適用を検討中。
分類 機能 機能概要と実現方式 拡張実装 拡張実装の格納パッケージ
オン・バッチ共通 テストコード作成支援 JUnit、Mockito、Springのテスト機能を利用して、単体テストコードや結合テストコードの実装を支援する機能を提供する。 - -

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors