Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Java Batch 仕様 (Public Review時点)

34,467 views

Published on

Public Review版を読み込んだときの勉強メモ。内容は今後改版される可能性がある。

  • Be the first to comment

Java Batch 仕様 (Public Review時点)

  1. 1. Java EE 7から加わるバッチ仕様Batch Applications for the Java Platform - JSR 352 7 Java EE Java Batch
  2. 2. Batch Applications for the Java Platform (JSR 352) Java EE 7から導入されるバッチフレームワーク Spring Batch のアーキテクチャを踏襲 アーキテクチャ定義のもと、APIとXMLの仕様を定義JSR352 の構成 (Public Review時点) アーキテクチャ仕様 Job/Step/Chunk アーキテクチャ全体像を定義 (第4章)ジョブXML仕様 API仕様 アーキテクチャを (第5章) (第6章) 『どうやって』実装するか Java Batch
  3. 3. Java Batchの主な機能1 - 実行順序制御  ジョブXMLと呼ばれる設定で、処理手順を定義する  処理の分岐、グループ化、並列実行が可能start STEP1 Flow (ステップ グループ化) STEP2-1 STEP2-2 end STEP3-1 Decision(条件分岐) Flow Split Flow Flow Split (ステップの並行実行) Java Batch
  4. 4. Java Batchの主な機能2 - 分割コミット レコード数が多い場合は、チェックポイントは必須要件 後述するchunk処理方式によって分割コミットを実現 ロールバックは最終コミットまで commit commit commit end × start ▼ ▼ ▼ 10行処理 10行処理 10行処理 障害発生 Java Batch
  5. 5. Java Batchの主な機能3 - エラーハンドリング バッチ失敗のよくある原因は不正な入力データ Java Batch ではエラーレコードを自動スキップする 1, AAA, BBB, CCC 2, DDD, EEE, FFF ???,,,,aaa,,aeae, スキップ 3, JJJ, KKK, LLL … バッチプログラム 99, ZZZ, ZZZ, ZZZ Java Batch
  6. 6. Java Batchの主な機能4 - 並行・分散実行 仕様上は明記されていないが、分散実行も可能? 引数にExternalizableを持つAPIがいくつかある (オブジェクトのシリアル化を意識している) Server B Server A STEP2-1 STEP2-2 STEP1 Server C STEP3-1 STEP3-2 Java Batch
  7. 7. ジョブスケジューラ と JavaBatch Java Batchには、cronのような時刻起動する機能はない cronやJP1から、Java Batchを呼び出して使う 順序管理のように被る領域もある (使い分け整理が必要) スケジューリング (時刻・周期起動) ジョブ実行順序管理 ジョブ実装サポート JP1:ジョブネット JavaBatch:ジョブXML (フレームワーク) 実行権限の管理 ジョブスケジューラ (cron/JP1/Tivoliなど) Java Batch Java Batch
  8. 8. Java Batch の位置付け 起動元は従来からあるバッチスケジューラ バッチAPの開発を簡単にするAPI提供がJava Batchの役割 ジョブスケジューラ (Cron/JP1など) ユーザ作成の 時刻起動 アプリケーション 各種APIの提供 データベース Servlet JPA Java Batch アプリケーションサーバ (JBoss等) OS/Java VM ファイル (CSV/XML 等) Java Batch
  9. 9. アーキテクチャ 7 Java EE Java Batch
  10. 10. アーキテクチャ JCLやCOBOLディベロッパに馴染み深いアーキテクチャ バッチ処理をメインフレームからJavaに移管させるため、 昔からある考え方をベースとした。 Job STEP2-1 JobOperator STEP1 STEP3 STEP4 STEP2-1 JobRepository Java Batch
  11. 11. ジョブ バッチ階層の最上位要素 複数のステップを組み合わせてジョブを構成する ステップ全体に関わる設定はジョブに定義する (例 : リスタート制御) Job STEP2-1 JobOperator STEP1 STEP3 STEP4 STEP2-1 JobRepository Java Batch
  12. 12. ジョブをXMLで表現すると ジョブの識別子。 JobOperator経由で起動時に このidを指定する。<job id="samplejob" restartable="false"> <step id="step1" next="step2" /> <step id="step2" /></job> Java Batch
  13. 13. ジョブをXMLで表現すると ジョブがリスタート可能か。 デフォルトはtrueのオプション属性。 (リスタートについては後述)<job id="samplejob" restartable="false"> <step id="step1" next="step2" /> <step id="step2" /></job> Java Batch
  14. 14. ジョブをXMLで表現すると 処理したいステップを定義。 Next属性で次のステップを指定。 (順序制御は色々種類があるので、後で詳しく解説)<job id="samplejob" restartable="false"> <step id="step1" next="step2" /> <step id="step2" /></job> Java Batch
  15. 15. ジョブインスタンスの考え方 JobInstance 1日1回のジョブであれば、毎日1つずつ生成される。 次の日にリスタートする場合は、前日のインスタンスを使う。 JobExecution 実行ごとに生成される。リスタート時には新たに生成される。 Job 『ファイル取り込み』ジョブ * JobInstance 2007/05/05 に実行する JobInstance 『ファイル取り込み』ジョブ * JobExecution 2007/05/05 に実行する JobExecution 『ファイル取り込み』ジョブ の1回目 Java Batch
  16. 16. ジョブとリスタート 1つのジョブインスタンスは、データとの対応を持つ 例えば、1月1日のジョブインスタンスは、1月2日に リスタートしても1月1日分のデータにアクセスする。 対象データが違うため、前日のリスタートジョブと 当日のジョブは並行実行することも可能。 1月1日分のジョブ JobInstance 実行 1/1のデータ ◎ 回目の 1/1 1 * 行 1/2のデータ △ タ ート実 1/2 リス /1分 1/3のデータ × ート時も1 JobExecution JobExecution リスタ タを処理 のデー 実行インスタンスは 実行毎に生成 Java Batch
  17. 17. ステップ ジョブに含まれるタスクを定義する。 各ステップの内容は、ユーザがコーディングする。 図のように、条件によって分岐することもできる。 Job STEP2-1 JobOperator STEP1 STEP3 STEP4 STEP2-1 JobRepository Java Batch
  18. 18. ステップ : 2つの処理方式 Chunk 方式 Batchlet方式 Item STEP ItemReader Processor ItemWriter STEP batchletexecute() execute() read() process() item process(item) item writer(item) ExitStatus ExitStatusExitStatus Chunk方式 Batchlet方式 Java Batch
  19. 19. Chunk方式 大規模なデータ処理に適した処理方式 1件ずつ読み込んで処理するのでメモリ消費を抑える コミット間隔の調整もしやすい Item STEP ItemReader Processor ItemWriterexecute() read() Chunk = 出力の塊 を示す item process(item) 複数レコードを処理して一度に 出力することも可能である。 item (詳細は次スライドで紹介) writer(item)ExitStatus Java Batch
  20. 20. Chunk方式 : まとめてコミット オーバヘッド低減のため、書き込みはまとめることも可能。 (chunk-size属性の設定) Item STEP ItemReader Processor ItemWriterexecute() read() item process(item) 1アイテム目の読み込みと処理 item read() item process(item) 2アイテム目の読み込みと処理 item writer(items) 処理が終わった2アイテムをExitStatus 書き込み、コミット Java Batch
  21. 21. Chunk方式 : アノテーション Reader/Processor/Writerはユーザがコード作成する。 ItemReader のコード例 @Named public class MyItemReader { @ReadItem MyBatchInputRecord read() throws Exception { // レコード読み取り処理 } }SpringBatchはインタフェースをベースに作成するが、JavaBatchでは、@ReadItemのようにアノテーション対応。 Java Batch
  22. 22. Chunk方式 : CDIとの連携 JavaBatchではSpringDIの代わりにCDIが使われるItemReader のコード例@Namedpublic class MyItemReader { @ReadItem MyBatchInputRecord read() throws Exception { // レコード読み取り処理 }}全てのコンポーネントに、@java.inject.Namedが必要。ジョブXMLからコンポーネント名を指定するため。 Java Batch
  23. 23. Chunk方式 : ジョブXML例 ステップの子要素としてchunkを定義する reader/processor/writer属性にはクラス名を定義 チャンクサイズの設定もXMLで可能 (デフォルトは10)<job id="samplejob" restartable="false"> <step id="step1" next="step2" > <chunk reader="MyReader" processor="MyProcessor" writer="MyWriter" chunk-size="2" /> </step> <step id="step2" /></job> Java Batch
  24. 24. Batchlet方式 ファイル/DB処理ではないステップに使う ファイル圧縮・転送・各種OSコマンドの実行 など Spring Batchのtaskletを同等のもの STEP batchlet execute() process() Chunkと比べて非常にシンプル。 STEPとbatchletが1対1となる。 ExitStatus ExitStatus Java Batch
  25. 25. Batchlet方式 : @Process @Processを付けたメソッドに処理を記述するだけ@Namedpublic class MyBatchLet{ @Process String process() throws Exception {...} @Stop void stopMe() throws Exception {...}}@Process バッチレットの処理内容を定義する@Stop JobOperator#stop()されたときにコールバックされる Java Batch
  26. 26. Batchlet方式 : ジョブXML例 ステップの子要素としてbatchletを定義する batchletを実装したクラス名を参照先として設定する <job id="samplejob" restartable="false"> <step id="step1" next="step2" /> <batchlet ref="MyBatchlet" /> </step> <step id="step2" /> </job> Java Batch
  27. 27. リスナ : ジョブ・ステップ実行前後にコールバック ジョブやステップの実行前後に呼び出される 一時ディレクトリ掃除・再生成などの前準備に使える 複数のリスナを定義することが可能ジョブレベルリスナ ジョブレベルリスナ (ジョブ実行前) (ジョブ実行後) Job listener listener STEP2-1 listener listener STEP1 STEP3 STEP4 STEP2-1 ステップレベルリスナ (ジョブ実行前後) Java Batch
  28. 28. JobOperator ジョブはジョブオペレータにより起動/再起動/停止される バッチ処理のコントロール役 Job STEP2-1 JobOperator STEP1 STEP3 STEP4 STEP2-1 JobRepository Java Batch
  29. 29. JobOperator : API BatchRuntimeクラスからインスタンスは取得できる 先ほどXMLで指定したジョブIDを起動のキーとする// factoryでインスタンスを取得JobOperator jobOperator = BatchRuntime.getJobOperator();// ジョブIDを指定して、ジョブを起動jobOperator.start("jobid1", property); <job id="jobid1"> Java Batch
  30. 30. JobRepository ジョブやステップの実行状態を保存する 保存された状態にはJobOperator経由でアクセスする 前述した、リトライ用のジョブインスタンスはここに保存 Job STEP2-1 JobOperator STEP1 STEP3 STEP4 STEP2-1 JobRepository Java Batch
  31. 31. 実行順序の制御 7 Java EE Java Batch
  32. 32. ステップ実行手順は複数の手段がある  Flow - ステップのグループ化  Sprit – 並行実行するフローの組み合わせを定義  Decision – ステップの終了ステータスに応じた条件分岐start STEP1 Flow (ステップ グループ化) STEP2-1 STEP2-2 end STEP3-1 Decision(条件分岐) Flow split Flow Flow split (ステップの並行実行) Java Batch
  33. 33. もっともシンプルなケース1つのジョブに、ステップが順処理で2つ start end STEP1 STEP2 next属性に次ステップを指定。 idが対象。<job id="samplejob"> <step id="step1" next="step2" /> <step id="step2" /></job> Java Batch
  34. 34. Flow ステップを一連のユニットとしてまとめる フローが終了したあとは、次エレメントに遷移 (ステップ、スプリット、デシジョン、他のフローのいずれか) start Flow end STEP1 STEP2-1 STEP2-1 STEP3<job id="samplejob"> <step id="step1"> <flow id="flow1" next="step3"> フローの中に複数ステップを定義。 <step id="step2-1"/> <step id="step2-2"/> next属性には、フローが完了した </flow> あとの次のステップを定義する。 <step id="step3" /></job> Java Batch
  35. 35. Split : 3つの構成要素 Split : 並列実行するフローの組み合わせを定義 Split Collector :  フロー実行結果を受け取り Split Analyzer に送る。 Split Analyzer :  Split Collectorから受け取った並行実行結果を処理する。 Flow Split Collectorstart end split split Flow Split Collector STEP2 analyzer Flow Split Collector Java Batch
  36. 36. Split : ジョブXMLの書き方 スプリットの中に並列実行したいフローを定義する 各フローは別々のスレッドで実行される <job id="samplejob"> <split id="split1" next="step2"> <flow id="flow1"> <step id="step1-1-1" next="step1-1-2"/> <step id="step1-1-2"/> </flow> <flow id="flow2"> <step id="step1-2-1" next="step1-2-2"/> <step id="step1-2-2"/> </flow> </split> <step id="step2" /> </job> Java Batch
  37. 37. Split Collector フロー結果をスプリットアナライザに中継する役割 各スプリットしたフローの実行スレッドで動作 FlowContextからデータを集め、Externalizableで返す FlowContextで 受け渡し Externalizableで 受け渡し Flow Split Collectorstart end split split Flow Split Collector STEP2 analyzer Flow Split Collector Java Batch
  38. 38. Split Collector : @CollectSplitData@Named コンテキストは自動的にpublic class SplitCollector { インジェクションされる @BatchContext FlowContext flowContext; Split Collector を示すアノテーション @CollectSplitData Externalizable collectSplitData() throws Exception { // コンテキストからFlowデータの取得 FlowData flowData = flowContext.getTransientUserData(); // Externalizable実装のユーザクラスを生成 ExternalizableBookData serial = new ExternalizableBookData(); serial.setName(flowData.getBookName()); // Externalizableを返す return serial; } 外部化(Externalizable)の結果を返す}Memo.仕様書には『The FlowContext is in scope when this method receives control.』とあるが、Split Collectorがどうやって各スプリットの結果を受け取るかはうまく読み取れていない。読み取れる範囲からは、上記のようにコンテキストからデータ取得すると思われる。 Java Batch
  39. 39. 参考 : java.io.Externalizable Serializableを継承したインタフェース オブジェクトの外部出力を自分でコーディングする。public class Book implements Externalizable { String title; int price; 引数なしコンストラクタを忘れると 復元時に InvalidClassException が public Book() {} 投げられるので注意。 public Book(String title, int price) { this.title = title; this.price = price; } @Override public void writeExternal(ObjectOutput out) throws IOException { out.writeUTF(title); out.writeInt(price); } 書き出し処理 @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { title = in.readUTF(); price = in.readInt(); } 復元処理} Java Batch
  40. 40. Split Analyzer Split Collectorから並行実行したフロー結果を集約する。 Collectorと異なり、シングルスレッドで動作する。 Collectorからデータが送られるたびに複数回起動する。 Split Collectorから 各フロー結果を受け取る Flow Split Collectorstart end split split Flow Split Collector STEP2 analyzer Flow Split Collector 集約・分析結果を出力 ファイル DBMS Java Batch
  41. 41. Split Analyzer : @AnalyzeCollectorData@Named SplitContextにアクセスできるpublic class SplitAnalyzer { @BatchContext Collectorから受け取ったデータを分析。 SplitContext splitContext; Collectorが書き出し回数分繰り返し呼ばれる。 (3スプリットであれば、3回呼ばれる) @AnalyzeCollectorData void analyze(Externalizable data) throws Exception{ // SplitCollectorから受け取ったデータを分析 } バッチステータスやスプリットの終了コードに @AnalyzeStatus 応じた処理を定義する。 void analyzeStatus(String batchStatus, String exitStatus) throws Exception { // スプリットの終了ステータスに応じた処理を行う }}Memo.仕様書には『The analyzeCollectorData method receives control each time a Partition collector sends itspayload.』と書かれていて、この解釈をCollectorからデータが送られるたびに毎回起動されると解釈した。一方、Analyzerはシングルスレッド起動としても明記されているため、一度に複数のCollectorからデータが送られた場合の挙動が仕様書からはうまく読み取れていない。 Java Batch
  42. 42. CollectorとAnalyzer : ジョブXMLの書き方<job id="samplejob"> <split id="split1" next="step2"> <flow id="flow1"> <step id="step1-1-1" next="step1-1-2"/> <step id="step1-1-2"/> </flow> <flow id="flow2"> <step id="step1-2-1" next="step1-2-2"/> <step id="step1-2-2"/> </flow> <collector ref="SplitCollector" /> <analyzer ref="SplitAnalyzer" /> </split> Splitエレメントの子エレメントとして定義。 <step id="step2" /> 参照先の実装クラス名をrefに指定する。</job> Java Batch
  43. 43. Decision ステップ・フロー・スプリットの終了ステータスをもとに 次の遷移先を選択する。 全部で4種類の遷移を指定できる <next> : 次エレメントへ遷移 <end> : 正常終了 <fail> : 異常終了 <stop> : 一時停止 <next on=”*” to=”STEP2”> STEP2 start Decision <end on=”stop step”> STEP1 exit status end <fail on=”fail step”> × 異常終了 Java Batch
  44. 44. バッチステータス と 終了ステータス バッチステータス  ジョブ全体の現在の状態を定義するパラメータ  状態の種類は仕様で定義されている  バッチランタイムにより設定される 終了ステータス Desicionの判定対象  ジョブ・ステップ・フロー・スプリットの終了ステータス  文字列値をユーザで定義する  ユーザが設定する。 何も設定されていない場合は、バッチステータスと同じ値。 Step Step exit status exit status start end Job exit status STEP1 STEP2 Batch Status (バッチ全体の現在の状態) Java Batch
  45. 45. 終了ステータスの設定方法 コンテキストのAPIで設定する リスナーで設定すると、Chunk処理と分離できて便利@Namedpublic class StepListener { @BatchContext StepContext stepContext; @BeforeStep public void beforeStep() throws Exception { // なんらかの前処理をする } Stepから特定の例外が投げられた場合に 終了ステータスを設定する。 @AfterStep public void afterStep() throws Exception { if (stepContext.getException() instanceof InvalidRecordException) { stepContext.setExitStatus("failed cause invalid records"); } }}Memo.仕様書にはリスナのコンテキストについて言及されていない。ステップ・リスナにはステップ・コンテキストがインジェクションできると思うが、上記のコードは推測の域である。 Java Batch
  46. 46. 参考 : バッチステータス一覧ステータス値 意味 バッチジョブは、ジョブオペレータのでスタートまたはリスタート操作されると、バッチ STARTING ランタイムによりSTARTING状態とされます。 ステップにおいても、実行開始直前はSTARTING状態となります。 バッチジョブがバッチランタイムにより既に開始されている状態です。 STARTED ステップにおいても、一度実行された後はSTARTED状態となります。 バッチジョブが、ジョブオペレータの停止操作、またはジョブXMLの<stop>エレメントに STOPPING よって停止要求された状態です。ステップにおいても、STOPPING状態となった場合は、 バッチランタイムによりまもなく停止処理が行われます。 バッチジョブが、ジョブオペレータの停止操作、またはジョブXMLの<stop>エレメントに STOPPED よって停止した状態です。ステップにおいても、バッチランタイムに停止された場 合、STOPPED状態となります。 バッチジョブが、未解決の例外、またはジョブXMLの<fail>エレメントによって終了した FAILED 状態です。ステップにおいても同様の条件でFAILED状態となります。 バッチジョブが、正常終了、またはジョブXMLの<end>エレメントによって終了した状態COMPLETED です。ステップにおいても同様の条件でCOMPLETED状態となります。 バッチジョブが、ジョブオペレータの『放棄(avandoned)』操作が行われたことを示す状ABANDONED 態です。放棄状態のジョブはジョブオペレータ経由で確認することはできますが、実行や リスタートを行うことはできません。履歴閲覧を目的に確認できるようになっています。 Java Batch
  47. 47. Decision : @Decide メソッド引数でコンテキストを取得する 終了コードを判定し、条件に応じて終了コードを上書き 終了コードが SUCCESS の場合、@Named SKIP に上書きする。public class Decider { @Decide public String decide(BatchContext context) throws Exception { String exitStatus = context.getExitStatus(); if ("SUCCESS".equals(exitStatus)) { return "SKIP"; } return exitStatus; }} Java Batch
  48. 48. Decision : ジョブXMLの書き方 Decisionではスキップの決定など動的な遷移制御ができる。 refにはDeciderのクラス名を設定<job id="samplejob"> <step id="step1"> <decision id="decision1" ref="Decisider"> <next on="SKIP" to="step3"/> <next on="*" to="step2"/> </decision> </step> <step id="step2" next="step3"/> DeciderからSKIPが返された場合は step3に進む。 <step id="step3"></job> それ以外はstep2に進む。 Java Batch
  49. 49. 実行順序の制御 : まとめ ジョブXMLとAPIを駆使して、様々な遷移が可能 主な手段として Flow、Decision、Split の3種類がある。 start STEP1 Flow (ステップ グループ化) STEP2-1 STEP2-2 end STEP3-1 Decision(条件分岐) Flow split Flow Flow split (ステップの並行実行) Java Batch
  50. 50. 例外ハンドリング 7 Java EE Java Batch
  51. 51. バッチ失敗の原因 : 不正なレコード不正なレコートが1行あっただけで、バッチ全体が失敗するバッチプログラム 処理対象のファイル Name, Age, Address SUCCESS 山田, 29, 千葉 SUCCESS 佐藤, 46, 埼玉 SUCCESS (数万行続く...) ... FAIL 破壊,,aaa,,99,,, Status FAIL Java Batch
  52. 52. バッチ失敗の原因 : 一時的に繋がらないDBセッションが一時的に足りないだけで、翌日に再実行。 100 Session ジョブA Max Session = 200 90 Session × ジョブB 一時的な過負荷により DBセッション数が足りない ジョブC Java Batch
  53. 53. バッチ失敗の原因 : パーミッションがない ディレクトリや一時ファイルの作成に失敗する。 一般ユーザ 拒否 × 一時ファイル root権限のディレクトリバッチプログラム (一般ユーザ) mk di r グループ書き込み権が × 足りない パーミッション744の ディレクトリ Java Batch
  54. 54. Java Batch 3つのエラーハンドリング スキップ  不正な入力データをスキップして、処理を継続 Chunk方式のステップが対象  リトライ  一時的な要因により失敗した処理を再実行  セッション不足、ロック待ち など リスタート  深刻なエラーが発生した場合はジョブを失敗させる  原因を取り除き、手動で再起動する Java Batch
  55. 55. スキップ Java Batchには次レコードにスキップしても良い例外を登録 (ジョブXMLに例外クラス名を記述) ItemReaderから投げられた例外がスキップ対象か判定する。 デフォルトは例外が1つでも発生すると、ジョブは失敗するJavaBatchランタイム Chunk方式 2.例外スロー Name, Age, Address スキップ対象例外 ItemReader 1. 例外 発生 山田, 29, 千葉InvaliedRecordException 3.スキップ許可 破壊,,aaa,,99,,, xxx Exception 佐藤, 54, 埼玉 △△△ Exception 4. スキップ Item 田中, 25, 東京 Processor 不正レコードを含んだ Item 入力ファイル Writer Java Batch
  56. 56. スキップ : <skippable-exception-classes><job id="samplejob" restartable="false"> スキップ上限数を設定 <step id="step1" next="step2" > <chunk reader="MyReader" processor="MyProcessor" writer="MyWriter" skip-limit="10"> <skippable-exception-classes> <include class="java.io.IOException" /> <exclude class="java.net.SocketException" /> </skippable-exception-classes> </chunk> スキップ対象の例外を設定。 </step> 子クラスも対象になるので、 <step id="step2" /> excludeで除外対象も要指定。</job>デフォルトは1つでも例外発生した時点でジョブ失敗。必ずスキップ対象例外を設定すること。ファイル全体が不正なものに備えて、スキップ上限数も必ず設定する。 Java Batch
  57. 57. スキップリスナ : @OnSkipedReadItem どのレコードをスキップしたのか記録することは重要 スキップ契機のリスナーであるスキップリスナでロギング @Named public class SkipListener { private static final Logger logger = Logger.getLogger(SkipListener.class); @OnSkipReadItem public void onSkipReadItem(Exception ex) throws Exception { // エラーメッセージのロギング logger.log(ex.getMessage()); } } Java Batch
  58. 58. スキップリスナ : ジョブXMLの書き方<job id="samplejob" restartable="false"> <step id="step1" next="step2" > <chunk reader="MyReader" processor="MyProcessor" writer="MyWriter" skip-limit="10"> <skippable-exception-classes> <include class="java.io.IOException" /> <exclude class="java.net.SocketException" /> </skippable-exception-classes> </chunk> <listeners> <listener ref="SkipListener" /> </listeners> </step> <step id="step2" /> スキップリスナはステップ階層の</job> リスナとして登録する。 ref属性にはクラス名を指定。 Java Batch
  59. 59. ItemProcessorで例外が発生したら? チャンクサイズ分、まとめて読み込まれる。 例外発生するとチャンク全体をロールバック。 読み込み済キャッシュは再利用される。 ロールバック chunk size分読み込み<chunk chunk-size=”x”> Cash Item Process Read Item Read Item Cash Item Process Write Item Read Item Cash Item Process トランザクション区間 Java Batch
  60. 60. ItemProcessor例外 : スキップ方法 キャッシュからアイテムをロードして再処理 例外の原因となったアイテムはスキップする キャッシュからロード Cash Item Process Read Item Read Item Cash Item スキップ Write Item Read Item Cash Item Process トランザクション区間 ▲ commit Java Batch
  61. 61. ItemWriterで例外が発生したら?  Writerは処理したデータをまとめて受け取る  どの入力がエラーの原因になったのかわからない → スキップ対象のItemを特定しにくいのが特徴 ロールバック ? Cash Item Process Read Item Cash Item ? Process Write ItemRead ItemRead Item ? Cash Item Process @WriteItems writeItems(List<T> items); Java Batch
  62. 62. ItemWriter例外 : スキップ方法 1アイテムずつキャッシュから読み込み処理 例外が発生したアイテムをスキップする → Processorと異なり、再度例外発生させてスキップ Cash Item Process Write Item 1アイテムずつトランザクションを分ける ▲ commit Read Item Read Item Read Item Cash Item Process Write Item × 例外アイテム スキップ Cash Item Process Write Item ▲ commit Java Batch
  63. 63. リトライ  一時的な原因の例外に対して効果的 (ネットワーク不安定/DBロック待ち など)  リトライを繰り返すと、性能に影響を与えるので注意  チャンク単位でリトライする インターネット Cash Item ProcessRead ItemRead ItemRead Item Cash Item Process Write Item × Cash Item Process 接続失敗 チャンク単位でリトライ Web Cash Item Process 成功 Service Cash Item Process Write Item Cash Item Process 外部のWebサービスは繋がりにくい場合もあるので、リトライが効果的 Java Batch
  64. 64. リトライ : <retryable-exception-classes><job id="samplejob" restartable="false"> リトライ回数を設定 <step id="step1" next="step2" > <chunk reader="MyReader" processor="MyProcessor" writer="MyWriter" retry-limit="3"> <retryable-exception-classes> <include class="javax.xml.ws.soap.SOAPFaultException" /> <exclude class="xxxException" /> </retryable-exception-classes> </chunk> リトライ対象の例外を設定。 </step> 子クラスも対象になるので、 <step id="step2" /> excludeで除外対象も要指定。</job>retry-limitを設定しない場合、デフォルトではリトライし続ける。必ずretry-limitに値を設定すること。 Java Batch
  65. 65. リトライリスナ : @OnRetryWriteException スキップと同様に、リトライもロギングが重要 リトライリスナをユーザが実装してロギングする@Namedpublic class RetryListener { private static final Logger logger = Logger.getLogger(RetryListener.class); @OnRetryWriteException public void onRetryWriteException(List<T> items,Exception ex) throws Exception { // エラーメッセージのロギング logger.log(ex.getMessage()); }} Java Batch
  66. 66. リトライリスナ : ジョブXMLの書き方<job id="samplejob" restartable="false"> <step id="step1" next="step2" > <chunk reader="MyReader" processor="MyProcessor" writer="MyWriter" skip-limit="10"> <retryable-exception-classes> <include class="javax.xml.ws.soap.SOAPFaultException" /> <exclude class="xxxException" /> </retryable-exception-classes> </chunk> <listeners> <listener ref="RetryListener" /> </listeners> </step> <step id="step2" /> リトライリスナはステップ階層の</job> リスナとして登録する。 ref属性にはクラス名を指定。 Java Batch
  67. 67. リトライとスキップを組み合わせる  リトライとスキップは通常組み合わせて設定する  例: 3回リトライして、失敗する場合は10回までスキップ<job id="samplejob" restartable="false"> リトライ回数 スキップ上限数 <step id="step1" next="step2" > <chunk reader="MyReader" processor="MyProcessor" writer="MyWriter" retry-limit="3" skip-limit="10"> <retryable-exception-classes> <include class="javax.xml.ws.soap.SOAPFaultException" /> </retryable-exception-classes> <skippable-exception-classes> <include class="javax.xml.ws.soap.SOAPFaultException" /> </skippable-exception-classes> </chunk> </step> <step id="step2" /> 同じ例外をretryable-exception-classesと</job> skippable-exception-classesに設定する Java Batch
  68. 68. リスタート 失敗したステップから再開する機能 スキップやリトライで対処できない問題に対応 (オペレータが手を入れないと治らない問題) チャンク処理内でのリスタートも可能 × ディスクフル発生 STEP1 STEP2 STEP3 STEP4 対向システムから 解凍 集計処理 次システムへ ファイル取得 集計データ転送 リスタート STEP3 STEP4 (STEP3から再開) 集計処理 次システムへ 集計データ転送 Java Batch
  69. 69. allow-start-if-complete の設定 業務によっては、ステップを1からやり直したい ジョブXMLへの設定で、ステップが完了していた場合に 再実行するか設定ができる 途中から再開(デフォルト) 最初から再開 STEP1 STEP1 STEP2 STEP2 STEP3 STEP3<step id="step1" <step id="step1" allow-start-if-complete="true"> allow-start-if-complete="false"> Java Batch
  70. 70. リスタート : ジョブXML restartable属性 : ジョブごとにリスタート可能か設定 Start-limit属性 : ステップごとにリスタート上限数を設定 リスタート可能か? (オプション。デフォルトtrue)<job id="samplejob" restartable="true"> <step id="step1" next="step2" start-limit="5" /> リスタート上限回数 <step id="step2" next="step3" allow-start-if-complete="false"/> <step id="step3" /></job> 完了していても再実行時に動かすか Java Batch
  71. 71. エラーハンドリングのポイント いかに『堅牢なバッチ』を作るかがポイント 堅牢とは  少々のエラーデータが混じっていても落ちない  一時的なエラーであれば自動的に復旧  オペレータの手をかけないバッチが堅牢なバッチ Java Batch が提供する手段  スキップ : 不正データのスキップ  リトライ : 一時的なエラーに対する自動再試行  リスタート : 途中から再開することで、再実行コスト低減 Java Batch
  72. 72. あとがき 7 Java EE Java Batch
  73. 73. 2013年上半期に仕様はfinalへ Public Reviewをもとに調査した  2013/1 現在は前述した仕様群は作業中  仕様確定に向けて、まだ内容は修正される可能性も Java EE 7 へ盛り込みへ  次のJava EE 仕様である『7』に盛り込まれる予定  Java EE 7 も2013年内にはリリース予定  EE 7 - GlashFishリリースまで、SpringBatchとの差分調査は難しい Javaで大規模バッチ構築のために、期待する標準です。 Java Batch

×