Java Batch 仕様 (Public Review時点)

73
Java Batch Java EE 7 Java EE 7から加わるバッチ仕様 Batch Applications for the Java Platform - JSR 352

description

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

Transcript of Java Batch 仕様 (Public Review時点)

Page 1: Java Batch 仕様 (Public Review時点)

Java Batch

Java EE

7Java EE 7から加わるバッチ仕様Batch Applications for the Java Platform - JSR 352

Page 2: Java Batch 仕様 (Public Review時点)

Java Batch

Batch Applications for the Java Platform (JSR 352)

Java EE 7から導入されるバッチフレームワーク Spring Batch のアーキテクチャを踏襲 アーキテクチャ定義のもと、APIとXMLの仕様を定義

JSR352 の構成 (Public Review時点)

ジョブXML仕様(第5章)

アーキテクチャ仕様 Job/Step/Chunk(第4章)

API仕様(第6章)

アーキテクチャ全体像を定義

アーキテクチャを『どうやって』実装するか

Page 3: Java Batch 仕様 (Public Review時点)

Java Batch

Java Batchの主な機能1 - 実行順序制御

ジョブXMLと呼ばれる設定で、処理手順を定義する 処理の分岐、グループ化、並列実行が可能

STEP1STEP2-1

Flow (ステップ グループ化)

STEP2-2

Decision(条件分岐)STEP3-1

Split

FlowFlow

FlowSplit (ステップの並行実行)

start

end

Page 4: Java Batch 仕様 (Public Review時点)

Java Batch

Java Batchの主な機能2 - 分割コミット

レコード数が多い場合は、チェックポイントは必須要件 後述するchunk処理方式によって分割コミットを実現

start endcommit▼

commit▼

commit▼

10行処理 10行処理 10行処理×

障害発生

ロールバックは最終コミットまで

Page 5: Java Batch 仕様 (Public Review時点)

Java Batch

Java Batchの主な機能3 - エラーハンドリング

バッチ失敗のよくある原因は不正な入力データ Java Batch ではエラーレコードを自動スキップする

バッチプログラム…

1, AAA, BBB, CCC2, DDD, EEE, FFF???,,,,aaa,,aeae, 3, JJJ, KKK, LLL

99, ZZZ, ZZZ, ZZZ

スキップ

Page 6: Java Batch 仕様 (Public Review時点)

Java Batch

Java Batchの主な機能4 - 並行・分散実行

仕様上は明記されていないが、分散実行も可能? 引数にExternalizableを持つAPIがいくつかある (オブジェクトのシリアル化を意識している)

Server A

Server B

Server CSTEP1

STEP2-1 STEP2-2

STEP3-1 STEP3-2

Page 7: Java Batch 仕様 (Public Review時点)

Java Batch

ジョブスケジューラ と JavaBatch

ジョブスケジューラ(cron/JP1/Tivoliなど) Java Batch

スケジューリング(時刻・周期起動)

ジョブ実行順序管理JP1:ジョブネット

JavaBatch:ジョブXMLジョブ実装サポート(フレームワーク)

実行権限の管理

Java Batchには、cronのような時刻起動する機能はない cronやJP1から、Java Batchを呼び出して使う 順序管理のように被る領域もある (使い分け整理が必要)

Page 8: Java Batch 仕様 (Public Review時点)

ジョブスケジューラ(Cron/JP1など)

Java Batch

Java Batch の位置付け

OS/Java VM

Servlet JPA Java Batch

アプリケーションサーバ (JBoss等)

ユーザ作成のアプリケーション

各種APIの提供時刻起動

起動元は従来からあるバッチスケジューラ バッチAPの開発を簡単にするAPI提供がJava Batchの役割

データベース

ファイル(CSV/XML 等)

Page 9: Java Batch 仕様 (Public Review時点)

Java Batch

Java EE

7アーキテクチャ

Page 10: Java Batch 仕様 (Public Review時点)

Java Batch

アーキテクチャ

JobOperator STEP1STEP2-1

STEP3 STEP4

JobRepository

STEP2-1

Job

JCLやCOBOLディベロッパに馴染み深いアーキテクチャ バッチ処理をメインフレームからJavaに移管させるため、 昔からある考え方をベースとした。

Page 11: Java Batch 仕様 (Public Review時点)

Java Batch

ジョブ

JobOperator STEP1STEP2-1

STEP3 STEP4

JobRepository

STEP2-1

Job

バッチ階層の最上位要素 複数のステップを組み合わせてジョブを構成する ステップ全体に関わる設定はジョブに定義する (例 : リスタート制御)

Page 12: Java Batch 仕様 (Public Review時点)

Java Batch

ジョブをXMLで表現すると

<job id="samplejob" restartable="false"> <step id="step1" next="step2" /> <step id="step2" /></job>

ジョブの識別子。JobOperator経由で起動時に

このidを指定する。

Page 13: Java Batch 仕様 (Public Review時点)

Java Batch

ジョブをXMLで表現すると

<job id="samplejob" restartable="false"> <step id="step1" next="step2" /> <step id="step2" /></job>

ジョブがリスタート可能か。デフォルトはtrueのオプション属性。

(リスタートについては後述)

Page 14: Java Batch 仕様 (Public Review時点)

Java Batch

ジョブをXMLで表現すると

<job id="samplejob" restartable="false"> <step id="step1" next="step2" /> <step id="step2" /></job>

処理したいステップを定義。Next属性で次のステップを指定。

(順序制御は色々種類があるので、後で詳しく解説)

Page 15: Java Batch 仕様 (Public Review時点)

Java Batch

ジョブインスタンスの考え方

Job

JobInstance

JobExecution

『ファイル取り込み』ジョブ

2007/05/05 に実行する『ファイル取り込み』ジョブ

2007/05/05 に実行する『ファイル取り込み』ジョブ の1回目

JobInstance1日1回のジョブであれば、毎日1つずつ生成される。次の日にリスタートする場合は、前日のインスタンスを使う。

JobExecution実行ごとに生成される。リスタート時には新たに生成される。

JobExecution

JobInstance

Page 16: Java Batch 仕様 (Public Review時点)

Java Batch

ジョブとリスタート 1つのジョブインスタンスは、データとの対応を持つ 例えば、1月1日のジョブインスタンスは、1月2日に リスタートしても1月1日分のデータにアクセスする。

対象データが違うため、前日のリスタートジョブと 当日のジョブは並行実行することも可能。

JobInstance

JobExecution

JobExecution

1月1日分のジョブ

1/1のデータ1/2のデータ1/3のデータ

◎△×

1/1 1回目の実行

1/2 リスタート実行

リスタート時も1/1分

のデータを処理

実行インスタンスは実行毎に生成

Page 17: Java Batch 仕様 (Public Review時点)

Java Batch

ステップ

JobOperator STEP1STEP2-1

STEP3 STEP4

JobRepository

STEP2-1

Job

ジョブに含まれるタスクを定義する。 各ステップの内容は、ユーザがコーディングする。 図のように、条件によって分岐することもできる。

Page 18: Java Batch 仕様 (Public Review時点)

Java Batch

ステップ : 2つの処理方式 Chunk 方式 Batchlet方式

STEP ItemReader ItemProcessor ItemWriter batchlet

execute()read()item

process(item)

itemwriter(item)

ExitStatus

STEP

execute()

ExitStatus

process()

ExitStatus

Chunk方式 Batchlet方式

Page 19: Java Batch 仕様 (Public Review時点)

Java Batch

Chunk方式 大規模なデータ処理に適した処理方式 1件ずつ読み込んで処理するのでメモリ消費を抑える コミット間隔の調整もしやすい

STEP ItemReader ItemProcessor ItemWriter

execute()read()item

process(item)

itemwriter(item)

ExitStatus

Chunk = 出力の塊 を示す複数レコードを処理して一度に出力することも可能である。(詳細は次スライドで紹介)

Page 20: Java Batch 仕様 (Public Review時点)

Java Batch

Chunk方式 : まとめてコミット

STEP ItemReader ItemProcessor ItemWriter

execute() read()item

process(item)

item

writer(items)

ExitStatus

read()item

process(item)

item

1アイテム目の読み込みと処理

2アイテム目の読み込みと処理

処理が終わった2アイテムを書き込み、コミット

オーバヘッド低減のため、書き込みはまとめることも可能。(chunk-size属性の設定)

Page 21: Java Batch 仕様 (Public Review時点)

Java Batch

Chunk方式 : アノテーション

@Namedpublic class MyItemReader { @ReadItem MyBatchInputRecord read() throws Exception { // レコード読み取り処理 }}

ItemReader のコード例

SpringBatchはインタフェースをベースに作成するが、JavaBatchでは、@ReadItemのようにアノテーション対応。

Reader/Processor/Writerはユーザがコード作成する。

Page 22: Java Batch 仕様 (Public Review時点)

Java Batch

Chunk方式 : CDIとの連携

@Namedpublic class MyItemReader { @ReadItem MyBatchInputRecord read() throws Exception { // レコード読み取り処理 }}

ItemReader のコード例

全てのコンポーネントに、@java.inject.Namedが必要。ジョブXMLからコンポーネント名を指定するため。

JavaBatchではSpringDIの代わりにCDIが使われる

Page 23: Java Batch 仕様 (Public Review時点)

Java Batch

Chunk方式 : ジョブXML例

<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>

ステップの子要素としてchunkを定義する reader/processor/writer属性にはクラス名を定義 チャンクサイズの設定もXMLで可能 (デフォルトは10)

Page 24: Java Batch 仕様 (Public Review時点)

Java Batch

Batchlet方式 ファイル/DB処理ではないステップに使う ファイル圧縮・転送・各種OSコマンドの実行 など Spring Batchのtaskletを同等のもの

batchletSTEP

execute()

ExitStatus

process()

ExitStatus

Chunkと比べて非常にシンプル。STEPとbatchletが1対1となる。

Page 25: Java Batch 仕様 (Public Review時点)

Java Batch

Batchlet方式 : @Process

@Namedpublic class MyBatchLet{ @Process String process() throws Exception {...} @Stop void stopMe() throws Exception {...}}

@Processを付けたメソッドに処理を記述するだけ

@Stop JobOperator#stop()されたときにコールバックされる

@Process バッチレットの処理内容を定義する

Page 26: Java Batch 仕様 (Public Review時点)

Java Batch

Batchlet方式 : ジョブXML例

<job id="samplejob" restartable="false"> <step id="step1" next="step2" />

<batchlet ref="MyBatchlet" /> </step> <step id="step2" /></job>

ステップの子要素としてbatchletを定義する batchletを実装したクラス名を参照先として設定する

Page 27: Java Batch 仕様 (Public Review時点)

Java Batch

リスナ : ジョブ・ステップ実行前後にコールバック

ジョブやステップの実行前後に呼び出される 一時ディレクトリ掃除・再生成などの前準備に使える 複数のリスナを定義することが可能

STEP1STEP2-1

STEP3 STEP4STEP2-1

Job

liste

ner

liste

ner

liste

ner

liste

ner

ジョブレベルリスナ(ジョブ実行前)

ジョブレベルリスナ(ジョブ実行後)

ステップレベルリスナ(ジョブ実行前後)

Page 28: Java Batch 仕様 (Public Review時点)

Java Batch

JobOperator

JobOperator STEP1STEP2-1

STEP3 STEP4

JobRepository

STEP2-1

Job

ジョブはジョブオペレータにより起動/再起動/停止される バッチ処理のコントロール役

Page 29: Java Batch 仕様 (Public Review時点)

Java Batch

JobOperator : API

// factoryでインスタンスを取得JobOperator jobOperator = BatchRuntime.getJobOperator(); // ジョブIDを指定して、ジョブを起動jobOperator.start("jobid1", property);

BatchRuntimeクラスからインスタンスは取得できる 先ほどXMLで指定したジョブIDを起動のキーとする

<job id="jobid1">

Page 30: Java Batch 仕様 (Public Review時点)

Java Batch

JobRepository

JobOperator STEP1STEP2-1

STEP3 STEP4

JobRepository

STEP2-1

Job

ジョブやステップの実行状態を保存する 保存された状態にはJobOperator経由でアクセスする 前述した、リトライ用のジョブインスタンスはここに保存

Page 31: Java Batch 仕様 (Public Review時点)

Java Batch

Java EE

7実行順序の制御

Page 32: Java Batch 仕様 (Public Review時点)

Java Batch

ステップ実行手順は複数の手段がある

STEP1STEP2-1

Flow (ステップ グループ化)

STEP2-2

Decision(条件分岐)STEP3-1

split

Flow

FlowFlow

split (ステップの並行実行)

start

end

Flow - ステップのグループ化 Sprit – 並行実行するフローの組み合わせを定義 Decision – ステップの終了ステータスに応じた条件分岐

Page 33: Java Batch 仕様 (Public Review時点)

Java Batch

もっともシンプルなケース

STEP1start

STEP2end

1つのジョブに、ステップが順処理で2つ

<job id="samplejob"> <step id="step1" next="step2" /> <step id="step2" /></job>

next属性に次ステップを指定。idが対象。

Page 34: Java Batch 仕様 (Public Review時点)

Java Batch

Flow ステップを一連のユニットとしてまとめる フローが終了したあとは、次エレメントに遷移(ステップ、スプリット、デシジョン、他のフローのいずれか)

start

STEP1 STEP2-1 STEP2-1

FlowSTEP3

end

<job id="samplejob"> <step id="step1"> <flow id="flow1" next="step3"> <step id="step2-1"/> <step id="step2-2"/> </flow> <step id="step3" /></job>

フローの中に複数ステップを定義。next属性には、フローが完了したあとの次のステップを定義する。

Page 35: Java Batch 仕様 (Public Review時点)

Java Batch

Split : 3つの構成要素

start

split

Flow

FlowFlow

splitanalyzer

end

STEP2

Split : 並列実行するフローの組み合わせを定義 Split Collector :

フロー実行結果を受け取り Split Analyzer に送る。 Split Analyzer :

Split Collectorから受け取った並行実行結果を処理する。

Split Collector

Split Collector

Split Collector

Page 36: Java Batch 仕様 (Public Review時点)

Java Batch

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>

Page 37: Java Batch 仕様 (Public Review時点)

Java Batch

Split Collector

start

split

FlowFlow

Flow

splitanalyzer

end

STEP2

Split Collector

Split Collector

Split Collector

フロー結果をスプリットアナライザに中継する役割 各スプリットしたフローの実行スレッドで動作 FlowContextからデータを集め、Externalizableで返す

FlowContextで受け渡し Externalizableで

受け渡し

Page 38: Java Batch 仕様 (Public Review時点)

Java Batch

Split Collector : @CollectSplitData@Namedpublic class SplitCollector { @BatchContext FlowContext flowContext;

@CollectSplitData Externalizable collectSplitData() throws Exception { // コンテキストからFlowデータの取得 FlowData flowData = flowContext.getTransientUserData();

// Externalizable実装のユーザクラスを生成 ExternalizableBookData serial = new ExternalizableBookData(); serial.setName(flowData.getBookName());

// Externalizableを返す return serial; }}

コンテキストは自動的にインジェクションされる

Split Collector を示すアノテーション

外部化(Externalizable)の結果を返す

Memo.仕様書には『The FlowContext is in scope when this method receives control.』とあるが、Split Collectorがどうやって各スプリットの結果を受け取るかはうまく読み取れていない。読み取れる範囲からは、上記のようにコンテキストからデータ取得すると思われる。

Page 39: Java Batch 仕様 (Public Review時点)

Java Batch

参考 : java.io.Externalizable Serializableを継承したインタフェース オブジェクトの外部出力を自分でコーディングする。public class Book implements Externalizable {

String title; int price;

public Book() {}

public Book(String title, int price) {this.title = title; this.price = price;

}

@Overridepublic void writeExternal(ObjectOutput out) throws IOException {

out.writeUTF(title); out.writeInt(price);}

@Overridepublic void readExternal(ObjectInput in) throws IOException,

ClassNotFoundException {title = in.readUTF(); price = in.readInt();

}}

引数なしコンストラクタを忘れると復元時に InvalidClassException が投げられるので注意。

書き出し処理

復元処理

Page 40: Java Batch 仕様 (Public Review時点)

Java Batch

Split Analyzer

start

split

Flow

FlowFlow

splitanalyzer

end

STEP2

Split Collector

Split Collector

Split Collector

Split Collectorから並行実行したフロー結果を集約する。 Collectorと異なり、シングルスレッドで動作する。 Collectorからデータが送られるたびに複数回起動する。

ファイル DBMS

Split Collectorから各フロー結果を受け取る

集約・分析結果を出力

Page 41: Java Batch 仕様 (Public Review時点)

Java Batch

Split Analyzer : @AnalyzeCollectorData

@Namedpublic class SplitAnalyzer { @BatchContext SplitContext splitContext;

@AnalyzeCollectorData void analyze(Externalizable data) throws Exception{ // SplitCollectorから受け取ったデータを分析 }

@AnalyzeStatus void analyzeStatus(String batchStatus, String exitStatus) throws Exception { // スプリットの終了ステータスに応じた処理を行う }}

SplitContextにアクセスできる

Collectorから受け取ったデータを分析。Collectorが書き出し回数分繰り返し呼ばれる。(3スプリットであれば、3回呼ばれる)

バッチステータスやスプリットの終了コードに応じた処理を定義する。

Memo.仕様書には『The analyzeCollectorData method receives control each time a Partition collector sends its payload.』と書かれていて、この解釈をCollectorからデータが送られるたびに毎回起動されると解釈した。一方、Analyzerはシングルスレッド起動としても明記されているため、一度に複数のCollectorからデータが送られた場合の挙動が仕様書からはうまく読み取れていない。

Page 42: Java Batch 仕様 (Public Review時点)

Java Batch

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> <step id="step2" /></job>

Splitエレメントの子エレメントとして定義。参照先の実装クラス名をrefに指定する。

Page 43: Java Batch 仕様 (Public Review時点)

Java Batch

Decision

start

STEP1Decision

exit status

STEP2

end

×

<next on=”*” to=”STEP2”>

<fail on=”fail step”>

<end on=”stop step”>

異常終了

ステップ・フロー・スプリットの終了ステータスをもとに 次の遷移先を選択する。

全部で4種類の遷移を指定できる<next> : 次エレメントへ遷移 <end> : 正常終了<fail> : 異常終了 <stop> : 一時停止

Page 44: Java Batch 仕様 (Public Review時点)

Java Batch

バッチステータス と 終了ステータス バッチステータス

ジョブ全体の現在の状態を定義するパラメータ 状態の種類は仕様で定義されている バッチランタイムにより設定される

終了ステータス ジョブ・ステップ・フロー・スプリットの終了ステータス 文字列値をユーザで定義する ユーザが設定する。

何も設定されていない場合は、バッチステータスと同じ値。

STEP1start

STEP2end

Stepexit status

Batch Status (バッチ全体の現在の状態)

Stepexit status

Job exit status

Desicionの判定対象

Page 45: Java Batch 仕様 (Public Review時点)

Java Batch

終了ステータスの設定方法 コンテキストのAPIで設定する リスナーで設定すると、Chunk処理と分離できて便利@Namedpublic class StepListener { @BatchContext StepContext stepContext;

@BeforeStep public void beforeStep() throws Exception { // なんらかの前処理をする }

@AfterStep public void afterStep() throws Exception { if (stepContext.getException() instanceof InvalidRecordException) { stepContext.setExitStatus("failed cause invalid records"); } }}

Stepから特定の例外が投げられた場合に終了ステータスを設定する。

Memo.仕様書にはリスナのコンテキストについて言及されていない。ステップ・リスナにはステップ・コンテキストがインジェクションできると思うが、上記のコードは推測の域である。

Page 46: Java Batch 仕様 (Public Review時点)

Java Batch

参考 : バッチステータス一覧

ステータス値 意味

STARTINGバッチジョブは、ジョブオペレータのでスタートまたはリスタート操作されると、バッチランタイムによりSTARTING状態とされます。ステップにおいても、実行開始直前はSTARTING状態となります。

STARTED バッチジョブがバッチランタイムにより既に開始されている状態です。ステップにおいても、一度実行された後はSTARTED状態となります。

STOPPINGバッチジョブが、ジョブオペレータの停止操作、またはジョブXMLの<stop>エレメントによって停止要求された状態です。ステップにおいても、STOPPING状態となった場合は、バッチランタイムによりまもなく停止処理が行われます。

STOPPEDバッチジョブが、ジョブオペレータの停止操作、またはジョブXMLの<stop>エレメントによって停止した状態です。ステップにおいても、バッチランタイムに停止された場合、STOPPED状態となります。

FAILED バッチジョブが、未解決の例外、またはジョブXMLの<fail>エレメントによって終了した状態です。ステップにおいても同様の条件でFAILED状態となります。

COMPLETED バッチジョブが、正常終了、またはジョブXMLの<end>エレメントによって終了した状態です。ステップにおいても同様の条件でCOMPLETED状態となります。

ABANDONEDバッチジョブが、ジョブオペレータの『放棄(avandoned)』操作が行われたことを示す状態です。放棄状態のジョブはジョブオペレータ経由で確認することはできますが、実行やリスタートを行うことはできません。履歴閲覧を目的に確認できるようになっています。

Page 47: Java Batch 仕様 (Public Review時点)

Java Batch

Decision : @Decide

@Namedpublic class Decider { @Decide public String decide(BatchContext context) throws Exception {

String exitStatus = context.getExitStatus(); if ("SUCCESS".equals(exitStatus)) { return "SKIP"; } return exitStatus; }}

メソッド引数でコンテキストを取得する 終了コードを判定し、条件に応じて終了コードを上書き

終了コードが SUCCESS の場合、SKIP に上書きする。

Page 48: Java Batch 仕様 (Public Review時点)

Java Batch

Decision : ジョブXMLの書き方

<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"/> <step id="step3"></job>

refにはDeciderのクラス名を設定

DeciderからSKIPが返された場合はstep3に進む。それ以外はstep2に進む。

Decisionではスキップの決定など動的な遷移制御ができる。

Page 49: Java Batch 仕様 (Public Review時点)

Java Batch

実行順序の制御 : まとめ

STEP1STEP2-1

Flow (ステップ グループ化)

STEP2-2

Decision(条件分岐)STEP3-1

split

FlowFlow

Flowsplit (ステップの並行実行)

start

end

ジョブXMLとAPIを駆使して、様々な遷移が可能 主な手段として Flow、Decision、Split の3種類がある。

Page 50: Java Batch 仕様 (Public Review時点)

Java Batch

Java EE

7例外ハンドリング

Page 51: Java Batch 仕様 (Public Review時点)

Java Batch

バッチ失敗の原因 : 不正なレコード

Name, Age, Address山田, 29, 千葉佐藤, 46, 埼玉

破壊,,aaa,,99,,,

...(数万行続く...)

処理対象のファイル

不正なレコートが1行あっただけで、バッチ全体が失敗する

バッチプログラム

SUCCESSSUCCESSSUCCESSFAIL

Status FAIL

Page 52: Java Batch 仕様 (Public Review時点)

Java Batch

バッチ失敗の原因 : 一時的に繋がらない

Max Session = 200

DBセッションが一時的に足りないだけで、翌日に再実行。

100 Session

ジョブA

ジョブC

ジョブB

90 Session

×一時的な過負荷によりDBセッション数が足りない

Page 53: Java Batch 仕様 (Public Review時点)

Java Batch

バッチ失敗の原因 : パーミッションがない

ディレクトリや一時ファイルの作成に失敗する。

バッチプログラム(一般ユーザ)

root権限のディレクトリ

パーミッション744のディレクトリ

×一般ユーザ拒否

×

一時ファイル

mkdir

グループ書き込み権が足りない

Page 54: Java Batch 仕様 (Public Review時点)

Java Batch

Java Batch 3つのエラーハンドリング

スキップ 不正な入力データをスキップして、処理を継続 Chunk方式のステップが対象

リトライ 一時的な要因により失敗した処理を再実行 セッション不足、ロック待ち など

リスタート 深刻なエラーが発生した場合はジョブを失敗させる 原因を取り除き、手動で再起動する

Page 55: Java Batch 仕様 (Public Review時点)

Java Batch

スキップ

ItemReaderName, Age, Address

破壊,,aaa,,99,,,

田中, 25, 東京ItemProcessor

ItemWriter

1. 例外発生

JavaBatchランタイムスキップ対象例外

InvaliedRecordException

xxx Exception

△△△ Exception

2.例外スロー

3.スキップ許可

Java Batchには次レコードにスキップしても良い例外を登録 (ジョブXMLに例外クラス名を記述)

ItemReaderから投げられた例外がスキップ対象か判定する。 デフォルトは例外が1つでも発生すると、ジョブは失敗する

不正レコードを含んだ入力ファイル

Chunk方式

山田, 29, 千葉

佐藤, 54, 埼玉4. スキップ

Page 56: Java Batch 仕様 (Public Review時点)

Java Batch

スキップ : <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" /></job>

スキップ上限数を設定

スキップ対象の例外を設定。子クラスも対象になるので、

excludeで除外対象も要指定。

デフォルトは1つでも例外発生した時点でジョブ失敗。必ずスキップ対象例外を設定すること。ファイル全体が不正なものに備えて、スキップ上限数も必ず設定する。

Page 57: Java Batch 仕様 (Public Review時点)

Java Batch

スキップリスナ : @OnSkipedReadItem

どのレコードをスキップしたのか記録することは重要 スキップ契機のリスナーであるスキップリスナでロギング

@Namedpublic class SkipListener {

private static final Logger logger = Logger.getLogger(SkipListener.class);

@OnSkipReadItem public void onSkipReadItem(Exception ex) throws Exception {

// エラーメッセージのロギング logger.log(ex.getMessage()); }}

Page 58: Java Batch 仕様 (Public Review時点)

Java Batch

スキップリスナ : ジョブ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属性にはクラス名を指定。

Page 59: Java Batch 仕様 (Public Review時点)

Read Item

Java Batch

ItemProcessorで例外が発生したら?

Read ItemRead Item

Process

Write Item

Cash Item

Process

Process

chunk size分読み込み<chunk chunk-size=”x”>

ロールバック

トランザクション区間

Cash Item

Cash Item

チャンクサイズ分、まとめて読み込まれる。 例外発生するとチャンク全体をロールバック。 読み込み済キャッシュは再利用される。

Page 60: Java Batch 仕様 (Public Review時点)

Java Batch

ItemProcessor例外 : スキップ方法

スキップRead ItemRead ItemRead Item

Process

Write Item

Cash Item Process

トランザクション区間

Cash Item

Cash Item

▲commit

キャッシュからロード

キャッシュからアイテムをロードして再処理 例外の原因となったアイテムはスキップする

Page 61: Java Batch 仕様 (Public Review時点)

Java Batch

ItemWriterで例外が発生したら?

Read ItemRead ItemRead Item

Process

Write Item

Cash Item Process

Cash Item

Cash Item Process

ロールバック

@WriteItemswriteItems(List<T> items);

???

Writerは処理したデータをまとめて受け取る どの入力がエラーの原因になったのかわからない→ スキップ対象のItemを特定しにくいのが特徴

Page 62: Java Batch 仕様 (Public Review時点)

Java Batch

ItemWriter例外 : スキップ方法

Read ItemRead ItemRead Item

Process

Cash Item Process

Cash Item

Cash Item Process

Write Item

Write Item

Write Item

▲commit

▲commit

× 例外アイテム

スキップ

1アイテムずつトランザクションを分ける

1アイテムずつキャッシュから読み込み処理 例外が発生したアイテムをスキップする

→ Processorと異なり、再度例外発生させてスキップ

Page 63: Java Batch 仕様 (Public Review時点)

Java Batch

リトライ 一時的な原因の例外に対して効果的 (ネットワーク不安定/DBロック待ち など)

リトライを繰り返すと、性能に影響を与えるので注意 チャンク単位でリトライする

Read ItemProcess

Write ItemCash Item

ProcessCash ItemProcessCash Item

Read ItemRead Item

インターネット

×

WebServiceProcess

Write ItemCash Item

ProcessCash ItemProcessCash Item

接続失敗

成功

チャンク単位でリトライ

外部のWebサービスは繋がりにくい場合もあるので、リトライが効果的

Page 64: Java Batch 仕様 (Public Review時点)

Java Batch

リトライ : <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" /></job>

リトライ回数を設定

リトライ対象の例外を設定。子クラスも対象になるので、

excludeで除外対象も要指定。

retry-limitを設定しない場合、デフォルトではリトライし続ける。必ずretry-limitに値を設定すること。

Page 65: Java Batch 仕様 (Public Review時点)

Java Batch

リトライリスナ : @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()); }}

Page 66: Java Batch 仕様 (Public Review時点)

Java Batch

リトライリスナ : ジョブXMLの書き方

リトライリスナはステップ階層のリスナとして登録する。

ref属性にはクラス名を指定。

<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>

Page 67: Java Batch 仕様 (Public Review時点)

Java Batch

リトライとスキップを組み合わせる リトライとスキップは通常組み合わせて設定する 例: 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" /></job> 同じ例外をretryable-exception-classesと

skippable-exception-classesに設定する

リトライ回数 スキップ上限数

Page 68: Java Batch 仕様 (Public Review時点)

Java Batch

リスタート

STEP1 STEP2 STEP3STEP3 STEP4

STEP3STEP3 STEP4

対向システムからファイル取得

解凍 集計処理

集計処理

次システムへ集計データ転送

次システムへ集計データ転送

×ディスクフル発生

リスタート(STEP3から再開)

失敗したステップから再開する機能 スキップやリトライで対処できない問題に対応 (オペレータが手を入れないと治らない問題)

チャンク処理内でのリスタートも可能

Page 69: Java Batch 仕様 (Public Review時点)

Java Batch

allow-start-if-complete の設定 業務によっては、ステップを1からやり直したい ジョブXMLへの設定で、ステップが完了していた場合に 再実行するか設定ができる

STEP1

STEP2

STEP3

STEP2

STEP3

STEP1

途中から再開(デフォルト) 最初から再開

<step id="step1" allow-start-if-complete="true">

<step id="step1" allow-start-if-complete="false">

Page 70: Java Batch 仕様 (Public Review時点)

Java Batch

リスタート : ジョブXML

<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>

リスタート可能か?(オプション。デフォルトtrue)

リスタート上限回数

完了していても再実行時に動かすか

restartable属性 : ジョブごとにリスタート可能か設定 Start-limit属性 : ステップごとにリスタート上限数を設定

Page 71: Java Batch 仕様 (Public Review時点)

Java Batch

エラーハンドリングのポイント

堅牢とは 少々のエラーデータが混じっていても落ちない 一時的なエラーであれば自動的に復旧 オペレータの手をかけないバッチが堅牢なバッチ

Java Batch が提供する手段 スキップ : 不正データのスキップ リトライ : 一時的なエラーに対する自動再試行 リスタート : 途中から再開することで、再実行コスト低減

いかに『堅牢なバッチ』を作るかがポイント

Page 72: Java Batch 仕様 (Public Review時点)

Java Batch

Java EE

7あとがき

Page 73: Java Batch 仕様 (Public Review時点)

Java Batch

2013年上半期に仕様はfinalへ

Public Reviewをもとに調査した 2013/1 現在は前述した仕様群は作業中 仕様確定に向けて、まだ内容は修正される可能性も

Java EE 7 へ盛り込みへ 次のJava EE 仕様である『7』に盛り込まれる予定 Java EE 7 も2013年内にはリリース予定 EE 7 - GlashFishリリースまで、SpringBatchとの差分調査は難しい

Javaで大規模バッチ構築のために、期待する標準です。