スライド 1

1
本資料では、JSR-352 で標準化されたJava実装のバッチ処理について概要を解説
します。
併せて、このJSR-352がLibertyではどのように実装されているのかについても併
せて解説します。
本資料を導入編としてご覧頂き、併せて別途公開されている
JavaEEアプリケーション設計ガイド シリーズの Javaバッチ編 で詳細を確認する、
という様に参照頂けますと、より理解が深まると思われます。
Java EE 7 アプリケーション設計ガイド - JSR-352 Batch Applications for
Java Platform 編
https://www.ibm.com/developerworks/jp/websphere/library/was/javaee7_
appguide/9.html
2
まずは、バッチ処理とはどのような処理なのか、そしてJSR-352ではバッチ処理を
どのように扱おうとしているのか、を概観してみます。
3
バッチ処理とは、簡単に言うと「データをまとめて処理する方式」といえます。
おそらく、長年Javaに触れてきた方々にとっては、オンライン・リアルタイム処理
がより身近だと思いますが、なぜバッチ処理が必要となるかというと、業務上、あ
るタイミングにならないとデータが揃わない、といった制約から仕方なくバッチ処
理で処理するケースや、ある程度データをまとめて処理し効率化を狙う、といった
性能的な要件から求められるケースがあります。
いずれの場合も、バッチ処理にバッチ処理固有の考慮点があります。追ってみてい
きましょう。
4
そもそも、なぜバッチ処理という処理形態は昔からあるのに、Javaで行われてこな
かったのでしょうか?実際JSR-352として標準化されたのは、Java EE 7からです。
以前は、COBOLなどの言語で実装しているケースが多かったようです。また、
Javaでの処理特性が、バッチ処理に向いていなかったという点もあるようです。
しかし、JavaとCOBOLなどの他言語で実装しているシステムを併せて運用してい
くとなると、それぞれ異なる特性に合わせた運用管理が必要になります。これはコ
ストを増加させる一因になります。更に、COBOLなどのをスキルを持つエンジニ
アが減少しているということもあり、それぞれのスキルを持ったエンジニアを育成
するというのもなかなかに大変なことです。
5
こういった諸問題を背景として、更にはH/Wの処理性能の増加を受けて、Javaで
バッチ処理を実装しようという機運が高まってきました。各ベンダーもJavaバッチ
製品を提供し、OSSでも提供されるようになります。
こうした実装の乱立から、次の流れとして標準化が進められます。Java EEで標準
化することによってスキルの共通化が計れると共に、オンライン処理と利用技術を
共通化することができるようになります。
そして、Java EE7 において、Javaバッチ処理は、JSR-352 Batch Applications
for Java Platformとして、晴れて標準化されました。
6
JSR-352は、いち早くLibertyで実装されています。
Libertyでは機能や仕様をfeatureの単位で有効化して利用しますが、Javaバッチ処
理も2つのfeatureとして提供されています。
主にJSR-352で規定されている仕様を提供するbatch-1.0と、JSR-352では規定さ
れていない主に運用・管理に関わる機能を提供するbatchmanagement-1.0です。
さらに、エンタープライズでの利用ももちろん想定しており、高可用性、拡張性を
備えるために、複数サーバーで構成するオプションも提供しています。
ここまでで、バッチ処理、Javaでのバッチ処理、Libertyでの対応、について概要
を説明しました。
7
ここから、Libertyでのバッチ処理とはどのようになるのか、その全体像を紹介し
ます。
8
JSR352、およびLibertyでの拡張機能全体を見通すとなるとそれなりに大変です。
まずは、全体像把握のために、5つの視点を設けて、順に確認していくこととしま
す。
スライド上、黒枠で囲っている1~3は、主にJSR-352で仕様化されている部分で
す。赤枠の4~5は、Libertyで独自に実装・提供している部分になります。
9
「1. アーキテクチャ」は、どのような仕組みでバッチ処理を行っているか、構成
要素にはどのようなものがあってどういう役割を担っているか、と解説します。
「2. ジョブ定義XML」においては、ジョブ定義の内容まで踏み込んで、どのよう
な処理タイプがあるのか、また、その制御はどのように行うか、どのように定義す
るのか、といった内容を解説します。
「3. API」では、バッチ処理の処理記述に使用するAPIを紹介します。
「4. インフラ・トポロジー」では、Libertyで採りうる定型的な構成パターンを紹
介します。
「5. 運用系機能」においては、ジョブ運用において必要となるその他の機能につ
いて紹介します。
10
ここからは、アーキテクチャーについての説明です。
11
JSR-352では、コンポーネントとして上記のような定義がされています。
「JobOperator」がジョブの操作のインタフェースとなり、「Job」を制御します。
「Job」は更に「Step」に細分化され、「Step」はデータの読み込み、処理、書き
出しといった典型的な処理を行います。
Job や Step の処理の状態や結果は、「JobRepository」に永続化され、再処理な
どに対応出来るような仕組みになっています。
12
JSR-352でのバッチ処理では、ジョブを処理の最大単位として定義します。この
ジョブの中に、1つ以上のステップを定義します。実際に何らかの処理を行うのは
この「ステップ」です。ジョブはジョブ・オペレータにより起動されて、処理の処理の経過・
結果はジョブ・リポジトリに保管されます。
ステップには、2つのタイプがあります。以降順に詳細を解説します。
13
ステップの処理形態の1つは、chunk型 です。
Chunk型では、データの塊から、1度に1つのItemを取り出し、処理をした上で、
出力する、という流れで処理します。出力のみ、まとめて実行します。どのように
まとめて出力するかというと、処理した件数、もしくは処理時間などの予め指定し
た条件に合致した場合に書き出しを行います。
この書き出しの間隔をどのように設定するかによって、処理効率が影響を受けます。
まとめて処理するほど効率は良くなりますが、何らかの理由でジョブが中断してし
まった場合、最後のコミットポイントから再開することになりますので、大分巻き
戻って処理を行う必要が出てくることになります。
14
次の処理形態は、batchlet型です。Batchlet型では、chunk型のように読み、処理、
書き、のような流れで処理を行うのではなく、一発完結で処理を行います。
ファイル転送、印刷、コマンド実行、のようなタスク実行で利用されます。
15
ジョブ・リポジトリも非常に重要なコンポーネントのひとつです。Libertyでは、
2つのタイプのリポジトリを提供しています。
1つは、メモリー・ベースのリポジトリです。メモリーへの保管ですので、そのプ
ロセスを停止した場合はジョブの実行情報も失われることになります。主に、開
発・テスト実施時に利用する形態です。
もうひとつは、データベースをリポジトリとして構成する方法です。この場合、
ジョブの情報はデータベースに永続化されますので、プロセスの障害や再起動を
行った場合でもジョブの実行情報を参照できます。本番環境などではこちらを利用
します。
16
ジョブ・リポジトリは、上記の様にLibertyのserver.xmlに定義します。
17
ここからは、ジョブの定義ファイルの説明と、どのようにジョブを制御するのか、
といった内容を解説します。
18
ジョブの定義は、JSL(Job Specification Language)というファイルに記述します。この
ファイルを、jar / war ファイル内の所定の場所に配置して、デプロイします。
このJSLのファイル名とジョブidは一致させておく必要があります。
19
ジョブは、実行要素と遷移要素で制御します。
実行要素で、処理の実行順序、分岐などを制御します。実行要素には、step(先に
説明したあのステップです)、実行要素をグループ化するflow、分岐を設定する
split、次に行う処理の判断を行うdecisionがあります。
もうひとつの遷移要素では、stepを実行した結果として次の処理を行うか、それと
もジョブを終了させるかを定義します。
これらの組み合わせてジョブの中の処理の流れを記述することになります。
20
上記は、実行要素の制御例です。
21
ここでは、JSR 352で規定されているクラスについて紹介します。
22
上記は、JSR-352で規定されているランタイムクラス群です。
23
JSR-352では、ジョブ実行に関連する複数のタイミングでListenerを定義して、処
理を差し込む事ができるようになっています。
上記は、そのタイミングと、対応するListenerです。
ここでは、どのようなものがあるか、の紹介に止めていますので、詳細については
仕様を参照するようにしてください。
24
ここからは、少々視点を変えて、バッチ処理を行うインフラ構成要素、サーバーの
配置、トポロジーについて解説します。
25
JSR-352においては、インフラの構成要素については特に規定がありません。
Libertyにおいては、上記のようにインフラを構成する構成要素を分けています。
まず、ランタイムとなるLibertyサーバーは、2つの役割が用意されています。実際
にバッチ処理を実行するためのExecutorと、Executorに処理を振り分ける
Dispatcherです。これらの役割は排他的ではなく、同じサーバーをDispatcher兼
Executorとして構成することも可能です。
このDispatcherからExecutorへのジョブの割り振りは、キューを介して行われま
す。
クライアントは、JobOperatorにRESTで直接ジョブを制御するか、コマンドライ
ンからコマンドを実行してジョブを制御します。
ジョブの実行情報をリポジトリに格納する事は既に記述しましたが、どのジョブ・
リポジトリを利用するかによって、実質的にバッチ処理環境のドメインを規定する
ことが出来ます。
26
具体的にどのような構成が考えられるか、というのを幾つか例示します。
まず、開発環境ではバッチ処理のロジックが意図したとおりに動くか否か、という
点が最も重要なポイントになると思われますので、単一のプロセスで完結するよう
な構成、すなわち、Executorのみをインメモリのジョブリポジトリと共に構成する、
という形態が一般的になるでしょう。
小規模の実働環境や、統合テストなどの実施時には、ジョブの実行状況が永続化さ
れるよう、ジョブリポジトリをDBなどで構成するケースが考えられます。
27
また、高可用性、拡張性が求められるEnterpriseでの利用の場合は、Dispatcherと
Executorを分離すると共に、それぞれを複数で構成する事が可能です。
Dispatcherの前段には、これらにRESTでのリクエストを振り分けるLoad
Balancerが必要になります。DispatcherからExecutorへの振り分けは、キューを
介して行われます。これらはすべて同じジョブリポジトリを共有します。
28
最後に、Libertyが提供する運用系機能を紹介します。
29
ジョブ操作のインターフェースとしては、
・RESTによる操作
・batchManagerコマンドによる操作
の2つの方法を提供しています。
いずれも最終的にはRESTでJobOperator(Executor)に対してアクセスを行うこ
とになります。
30
上記は、RESTによるジョブ操作の使用例です。
POSTでアプリケーション名、モジュール名、JobXMLファイル、プロパティーを送信することで、ジョ
ブをサブミットしています。
31
結果として、ジョブサブミットの結果が返信されます。
この状態で、ジョブの実行が完了しているわけではなく、あくまでもサブミットし
た結果がインスタンスIDとともに返信されるのみです。
最終的なジョブの実行結果は、ジョブのステータスを同様に問い合わせることに
よって確認します。
32
上記は、batchManagerコマンドの使用方法です。
33
Libertyでは、ジョブの実行やジョブの状態の問い合わせなどの権限を3つのロール
に対応付けています。
このロールをユーザーに対して割り当てることによって、そのユーザーが許容され
るアクションを設定することになります。
3つのロールとして、
・すべての操作が可能な batchAdmin
・新規のジョブのサブミットと自分がサブミットしたジョブの操作を行える、
batchSubmitter
読み取り権限のみ保持するbatchMonitorが存在しています。
34
ジョブの状態はリポジトリにも書き出されますが、ジョブ実行時のログはジョブロ
グとして書き出されます。
ジョブログは、インスタンス、実行単位に出力されます。
Libertyでは、規定 行数の出力時に自動でローテーションする機構を備えています。
また、当然ながらジョブログの出力の詳細度は調整可能ですので、問題判別時等で
は出力レベルを挙げて挙動を観察するといったことも可能です。
35
ここまで、5つの視点でLibertyでのバッチ処理を紹介してきました。
全体像の把握についてはここで紹介した内容レベルでよいかもしれませんが、より
詳細な採用検討や検証を行おうとする場合には、別で発行しているJSR-352のガイ
ド、およびLibertyでの実装についてのガイドを参照ください。またインフラ構成
は組み合わせによって様々な形態を採る事が可能です。アンチパターンを含め、ト
ポロジー・デザインをまとめた資料もありますので、是非参照してみてください。
是非、Libertyでのバッチ処理を皆様の業務にお役立てください!
36
37
38