JobStreamerではじめるJavaBatchのクラウド分散実行

51
JobStreamerではじめる JavaBatchのクラウド分散実行 kawasima 川島義隆 JJUG CCC 2015 Spring F-7 kawasima

Transcript of JobStreamerではじめるJavaBatchのクラウド分散実行

JobStreamerではじめるJavaBatchのクラウド分散実行

kawasima

川島義隆

JJUG CCC 2015 Spring F-7

kawasima

https://github.com/kawasima/

http://twitter.com/kawasima/

http://www.slideshare.net/kawasima/

http://qiita.com/kawasima/

Javaな場でしゃべるのは初めてなので、

お手柔らかにお願いします!

JavaBatchを始めてみよう

JSR352 JavaBatchとは

Job

JobInstance

Step

Batchlet

Chunk

ItemReader

ItemProcessor

ItemWriter

JobExecution StepExecution

実装するコンポーネント

XMLで定義する

ジョブ実行をあらわすコンポーネント

*11

0..1

0..1

JSR352 JavaBatchのはじめ方①Batchlet または ItemReader /

ItemProcessor / ItemWriterを実装する。

②batch-jobs.xmlを書く。

③起動するプログラムを書く。

Batchletを実装する@Named

public class MyBatchlet extends AbstractBatchlet {

@Inject

JobContext jobContext;

private Properties jobProperties;

@Override

public String process() throws Exception {

jobProperties = jobContext.getProperties();

String value1 = jobProperties.getProperty("jobProp1");

// ...

return "Processed";

}

}

基本的にはこの1メソッドを実装するだけまぁ簡単

batch-jobs.xml<job id="jasperReportsTest"

xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="1.0">

<step id="step1">

<batchlet ref="jasperReportsBatchlet">

<properties>

<property name="resource" value="movies-2012.csv"/>

<property name="useFirstRowAsHeader" value="true"/>

<!-- \n as record/row delimiter -->

<property name="recordDelimiter" value="&#xA;"/>

<property name="charset" value="UTF-8"/>

<property name="template" value="movies.jasper"/>

<property name="outputType" value="pdf"/>

<property name="outputFile" value="#{systemProperties['java.io.tmpdir']}/report.pdf"/>

<property name="reportParameters" value="#{jobParameters['reportParameters']}"/>

</properties>

</batchlet>

</step>

</job>

It's so easy!!!!...?

起動プログラム

ExcelにジョブのIDをかくじゃろ

( ^ω^)

⊃ ⊂

というストーリーがみえる

これをこうして…

( ^ω^)

≡⊃⊂≡ こうじゃ( ^ω^)⊃ ⊂

JSR352 JavaBatchを始めると…

①Batchlet または ItemReader / ItemProcessor / ItemWriterを実装する。

②batch-jobs.xmlを書く。

③起動する。

ツライ…

くやしい…でも…ジェネレータ作っちゃう!

ジョブの組み立てをもっと簡単に!

ジョブの起動をもっと簡単に!

バッチコンテナの運用● 常駐コンテナで動かすことのメリット

– 小さなジョブがたくさん動いても、JVM起動のオーバヘッドがない。

● 常駐サーバで複数ジョブ動かすことへの漠然とした不安

– サーバが死んだときのリカバリは?– 特定のジョブが別の重いジョブに影響を与えるのは避けたい?

Disposable batch containersジョブの実行環境は、リソース専有することなく、使い捨てできるとよい。

– 空いてるサーバに優先的にディスパッチ

– 複数のバッチサーバがいて、1台死んでも簡単にフェイルオーバーできるといいなぁ

でも、バッチアプリのデプロイが面倒そうだ

ジョブの実行環境をDistributedに!

Deployの手間はゼロに!

ジョブスケジューラにまつわる思い出

• 動いちゃいけないのに、動いてしまった。• 日付を間違えて登録して、起動しなかった。• GUIから漂う昭和感。

ジョブがいつ動くかをもっと分かりやすく!

できればもっとモダンに!

なので

つくってみた

https://github.com/job-streamer(EPLライセンス)

JobStreamerが変える世界できるようになること 不要になるもの

管理コンソール上でのGUIによるジョブ組み立て

ジョブ XML

REST APIによるジョブの起動 ジョブ起動用のJavaアプリ

スケジュール実行 JP1のようなスケジューラシンプルな分散実行 バッチサーバのフェイルオーバー設計エージェントへを起動するだけでジョブが動く、ノーデプロイ・ノーコンフィギュレーション環境

VagrantやDockerなどによるバッチサーバの設定やデプロイの自動化

エージェントの稼働状況モニタリング ZABBIXなどによるバッチサーバの監視

リアルタイムなログ収集 fluentdなどによるログの収集

すべてがS式になる Emacs以外の環境

JobStreamerの構成

管理コンソール

Jobの定義Jobの実行ログ

コントロールバス

JavaBatchコンポーネント● Batchlet● ItemReader● ItemProcessor● ItemWriter

Load class

● ジョブの登録/編集/削除● スケジューリング● ジョブの実行● 実行結果の確認

ジョブの実行リクエスト● Load class● 実行状態の送信● サーバ負荷状態の送信

実行エージェント

Datomic

No deploy,no configuration

コントロールバス

● ジョブの登録やジョブのディスパッチなどを司る。– ジョブの登録/編集/削除– ジョブのスケジューリング– ジョブのディスパッチ/実行結果・ログの収集– エージェントのモニタリング

● REST APIですべての操作が可能。

管理コンソール

● コントロールバスのWebインタフェース– ジョブのGUI組み立て– 実行ログの閲覧– ジョブのタイムライン表示

● Single page applicationでサクサク動く!

エージェント

● 実際にジョブが実行されるサーバ● REST APIですべての操作が可能。● 実装はJBossのJberet

– クラスローダをWebSocketClassLoaderに入れ替えて使う。

● Dockerfileもついてるので、docker runして使うことも可能。

Datomic (おまけ)

● Jobの定義や実行ログなどは、すべてDatomicに格納される。

● SPoFのコントローラバスからのみ繋ぐので、

Freeライセンスでも本番運用可能。

http://www.datomic.com/

Datomicとは...

今をときめくAppend-onlyなデータベース

– ストレージ(としてのDB)

は別に選択できる。

● Dynamo DB● Infinispan● Mysqlなどなど

Why Datomic?Clojureから自然な形でクエリが書ける。

※ クエリはDatalogという論理プログラミングの伝統的な記法

Demo

Jobの実行状況をみる(一覧)

Jobの実行状況をみる(タイムライン)

アプリケーションを登録する

専用のMavenプラグインがあります

% mvn job-streamer:deploy

Jobを新規登録する

Jobの詳細をみる

Jobをスケジューリングする

実行履歴とログをみる

エージェントをみる

エージェントをモニタリングする

例) CSVをJPAでOracleにロードする

例) シェルスクリプトを動かすシェルスクリプトをクラスパスに入れておき…

こんなジョブを流す

エージェントで実行され、STDINがログとして記録される

Architecture

WebSocketClassLoader

クラスロードをWebSocket経由でリモートからよぶ。リソースファイルもロード可能。https://github.com/kawasima/websocket-classloader/

Maven Centralにおいてあるので、お気軽にお試しください

WebSocketClassLoaderのしくみ

WebSocketClassLoaderClassProvider

WebSocket Handshake / Connect

LoadClass request

Class binary format

Encoded by fressian

JSR356準拠で動くので、dependenciesは0(EEサーバ以外で動かすには、Undertowなどにデプロイする)

JSR356のServerEndpointを実装している。

JSR356のClientEndpointを使ってloadClassリクエストを送る。ローカルキャッシュに最新のクラスがあればそっちを使う。

JberetでのClassLoaderの置き換え

BatchSEEnvironmentクラスにて...

こんな実装になっちゃっているので、WebSocketClassLoaderを返すように置き換えている。

Jobが実行されるまでの流れ

Full clojure

①サーバ実装 → liberator ②Javascript→ Clojurescript→Om (React layer)

③ Stylesheet → garden④ SQL → datalog

すべてがS式に!

om

ReactをClojurescriptから使うことができる。

Circle CIのUIはomで作られています。

(https://github.com/circleci/frontend)

https://github.com/omcljs/om

liberatorAPIを宣言的に書くことができる。

liberatorのデシジョングラフどこを、どう通ってレスポンスを返したか、リクエストごとに表示される

サーバ間WebSocket(JSR356)

Agentの状態の変化をリアルタイムにControl Busが受け取るために、WebSocketを使って通知

JSR356の仕様としてClientもあるので、実装は非常に簡単。

ログのリアルタイム書き込み(WebSocketAppender)

logbackのアペンダとしてセットし、ログを

WebSocket経由でログサーバにリアルタイムで送る。

https://github.com/kawasima/logback-websocket-appender/

これもMaven Centralにおいてあるので、よろしければどうぞお使いください

RRD4J

Agentのリソースモニタリングは、RRDToolのJavaクローンのRRD4Jを使うと簡単にPure Javaでグラフが書ける。

(https://github.com/rrd4j/rrd4j)

今後の予定

● SplitやDecisionなどのJSR352のフルサポート

●マルチプロジェクトのサポート

●異常時の通知の仕組み実装

● ファイル到着トリガやDBステータス変更トリガのサポート

● スケジュール登録機能の強化(ウィザードや営

業日カレンダーの登録など)

まとめ

● JavaBatchに対する不満もJobStreamerを使えば解消するよ

● No deploy, No configurationなので、簡単に分散実行できちゃうよ

● なによりJavaBatchを気軽に試せるよ

みなさまの(or User Developer)としてのご参加を心よりお待ちしております!

github.com/job-streamer