JSUG勉強会 2017年その4 ~ Springを使ったバッチアプリケーション特集 に行ってきた

JSUG勉強会 2017年その4 に行ってきました。簡単に所感をまとめます。

jsug.doorkeeper.jp

今回のテーマは Spring を使ったバッチアプリケーション特集です。

バッチは地味だが役に立つ

www.slideshare.net

  • 処理モデル
    • タスクレットモデル
      • 1ステップに対して1タスクレットの構成
      • シンプル
      • 処理をまとめたい場合など
    • チャンクモデル
    • 処理モデルはジョブごとに選択する
  • 起動方法
    • 同期実行
      • スクリプトなどからジョブを叩く
      • 複数のジョブを組み合わせるケースなど
    • 非同期実行
      • Webコンテナ経由でジョブを叩く
      • バッチ実行に即時性が求められるケースなど (ユーザ操作とか)
  • データ入出力
    • ファイル/DB
    • Bean定義の中でファイル読み込みやDB書き込みの定義が書ける
    • MyBatis
  • フロー制御
    • Job と Step でフローを制御する
    • シーケンシャルフロー
      • 後続ステップを指定してステップを繋げていく
      • リターンコードで分岐を定義できる
    • step の同時実行 (並列処理/多重処理) が可能
  • ジョブ管理機能
    • 障害発生時のリスタート制御
    • 二重起動防止
  • Webコンテナによる非同期実行の課題
  • ファイルアクセスにおける課題
    • Spring Batch では1行を1レコードとして扱う
    • マルチバイト文字が正しく処理できない
    • CSVエスケープ処理してない (クォートで囲った中のカンマが区切りとして見なされる)
  • TERASOLUNA Batch Framework

  • 業務DBを別途用意する場合、2フェーズコミットが必要になるか

    • ジョブの実行結果は JobRepository に入っているのでどこまで処理できたかは分かるはず
    • 2フェーズコミットにしても不整合が発生する可能性はある
    • 2フェーズコミットは使わず、不整合が発生した場合の運用対処を用意するのもアリ

www.slideshare.net

  • JJUG CCC 2017 Spring の再演
  • 現在のレポートシステムは第3世代
    • RabbitMQ + Spring Cloud Stream で構成されている
    • 第2世代が Spring Batch アプリだったので Spring Boot アプリに移行し易かった
    • Spring Cloud では Spring Boot アプリであることが前提
  • Spring Cloud Stream
    • 各サービスがマイクロサービス
      • サービス間はメッセージで連携する
    • Publisher / Subscriber
  • ポーリング型からイベントドリブンにすることでスループットが向上
  • Source (Publisher) -> RabbitMQ -> Sink (Subscriber)
    • output と input 両方で同じ destination を指定する
      • ただし、このままだとスケールしたすべての Sink にジョブが送られてしまう
    • consumer groups でグループ化する
      • グループ内の1つの Sink にジョブが送られるようになる
  • 大量のジョブを処理すると、Job管理テーブルに同時に大量のINSERTが発生する
    • RDBがハングした結果、RabbitMQにメッセージが戻ってくる
      • 空いてる Subscriber に再送する
    • デフォルト3回リトライしてだめだったらメッセージが消える
      • とりあえず上限値を5に上げる
    • Dead Letter Queue
      • 5回リトライしてだめならエラー処理用のサーバにメッセージを送る
      • Dead Letter Queue からメッセージを再送信する
  • API, Batch の Spring Boot 化
    • API : war -> jar (with Jetty)
    • Batch : 1アプリを1jarにする (機能単位でjarにする)
      • 常駐バッチは spring.batch.job.enabled=false にする (起動時にジョブを実行しない)
    • Spring Boot アプリを Web アプリとして起動しない
      • ポートの管理が大変
      • 1サーバに複数プロセスとする
      • spring.main.web-environment=false を設定する
        • Spring Boot 2.0 以降は非推奨
        • 代わりに WebApplicationType を使う

TERASOLUNA は、フレームワーク本体だけでなくドキュメントも充実してるので、とても助かります。これまで Tasklet 構成のバッチしか作ったことがないので、機会があればチャンクモデルも使ってみたいです。Spring Batch は、その処理モデルに合わせて設計するのがキモな気がする。(特にチャンクモデルの場合)

Spring 徹底入門の Spring Batch 編をダウンロードしたけど、まだちゃんと読めてないので勉強しよう。

これまで、Spring Cloud を使ったことがないので、JSUG の勉強会で Spring Cloud 関連のテーマになると理解が追い付かない...。