Create: 2014/09/22
LastUpdate: 2014/09/22
Jobscheduler FAQの「Start of JobChains by Events, Configurations for EventHandler in data file」 では、複雑なジョブの組み合わせをイベントで制御します。動作確認してみたかったのですが、サンプルコードが提供されていないようなので、自分で作ってみました。
ちなみに、JobScheduerFAQ には JOE での作成手順が記載されています。(JOEの画面はドイツ語ですが。。)
動作確認は、JobScheduler1.7 を使用しています。
シナリオ
下図のような流れで、7つの帳票(JobRep10-JobRep70)を作成するジョブを考えます。
JobScheduler への実装方法
Job10系(10-11-12-13)とJob20系(20-21-22-23) を以下のようなJobChainにして、個別に実行することにします。
- JobChain10: Job10、Job11、Job12、Job13
- JobChain20: Job20、Job21、Job22、Job23
下図はイベントフローです。後述するイベント制御ファイルを作成するときの設計図になります。
イベント名は、"ev_<イベントを作成したジョブ>_<イベントを受信するジョブ>" とします。
ボックスの右端にあるイベント名は、そのジョブが生成します。OKは正常時、NOKは異常時、指定がない場合はジョブ起動時に生成することにします。
ボックスの左側にあるイベント名は、そのジョブの起動条件です。記載されたイベントが全部そろったらジョブを実行します。
今回作成したファイルは、以下のとおり。
debug.pl については、「 [CentOS6][SOS JobScheduler] 複数のJobChain 並列に実行し、複数の同期ポイントを設定する」を参照してください。
$ tree ./live/sample2 ├── EventAdd.job.xml ・・・・・・・ イベント生成 ├── Job10.job.xml ・・・・・・・・ テストジョブ ├── Job11.job.xml ・・・・・・・・ テストジョブ ├── Job12.job.xml ・・・・・・・・ テストジョブ ├── Job13.job.xml ・・・・・・・・ テストジョブ ├── Job20.job.xml ・・・・・・・・ テストジョブ ├── Job21.job.xml ・・・・・・・・ テストジョブ ├── Job22.job.xml ・・・・・・・・ テストジョブ ├── Job23.job.xml ・・・・・・・・ テストジョブ ├── Job31.job.xml ・・・・・・・・ テストジョブ ├── Job32.job.xml ・・・・・・・・ テストジョブ ├── Job33.job.xml ・・・・・・・・ テストジョブ ├── Job41.job.xml ・・・・・・・・ テストジョブ ├── Job42.job.xml ・・・・・・・・ テストジョブ ├── Job43.job.xml ・・・・・・・・ テストジョブ ├── JobChain10.config.xml ・・・・・ JobChain10用の設定ファイル ├── JobChain10.job_chain.xml ・・・ JobChain10 ├── JobChain20.config.xml ・・・・・ JobChain20用の設定ファイル ├── JobChain20.job_chain.xml ・・・ JobChain20 ├── JobChain31.config.xml ・・・・・ JobChain31用の設定ファイル ├── JobChain31.job_chain.xml ・・・ JobChain31 ├── JobChain32.config.xml ・・・・・ JobChain32用の設定ファイル ├── JobChain32.job_chain.xml ・・・ JobChain32 ├── JobChain33.config.xml ・・・・・ JobChain33用の設定ファイル ├── JobChain33.job_chain.xml ・・・ JobChain33 ├── JobChain41.config.xml ・・・・・ JobChain41用の設定ファイル ├── JobChain41.job_chain.xml ・・・ JobChain41 ├── JobChain42.job_chain.xml ・・・ JobChain42 ├── JobChain43.config.xml ・・・・・ JobChain43用の設定ファイル ├── JobChain43.job_chain.xml ・・・ JobChain43 ├── JobChainRep10.job_chain.xml ・・ JobChainRep10 ├── JobChainRep20.job_chain.xml ・・ JobChainRep20 ├── JobChainRep30.job_chain.xml ・・ JobChainRep30 ├── JobChainRep40.job_chain.xml ・・ JobChainRep40 ├── JobChainRep50.job_chain.xml ・・ JobChainRep50 ├── JobChainRep60.job_chain.xml ・・ JobChainRep60 ├── JobChainRep70.job_chain.xml ・・ JobChainRep70 ├── JobRep10.job.xml ・・・・・・・ テストジョブ(帳票) ├── JobRep20.job.xml ・・・・・・・ テストジョブ(帳票) ├── JobRep30.job.xml ・・・・・・・ テストジョブ(帳票) ├── JobRep40.job.xml ・・・・・・・ テストジョブ(帳票) ├── JobRep50.job.xml ・・・・・・・ テストジョブ(帳票) ├── JobRep60.job.xml ・・・・・・・ テストジョブ(帳票) ├── JobRep70.job.xml ・・・・・・・ テストジョブ(帳票) └── debug.pl ・・・・・・・・・・・ デバッグファイル出力用 $ tree ./events/ └── Sample2Events.actions.xml・・・ イベント制御ファイル
JobChain10、JobChain20
JobChain10、JobChain20の内容は以下のとおり。(JobCain20は数字を読み替え)
JobChainでは、JobChainSplitterでジョブを並列実行し、ジョブが終了したら EventAddジョブでイベントを生成します。
<?xml version="1.0" encoding="ISO-8859-1"?> <job_chain title="JobChain10"> <job_chain_node state="StartJobChain10" job="/sos/jitl/JobChainStart" next_state="Job10" error_state="!error"/> <job_chain_node state="Job10" job="Job10" next_state="SplitJobChain10" error_state="!error"/> <job_chain_node state="SplitJobChain10" job="/sos/jitl/JobChainSplitter" next_state="EndJobChain10" error_state="!error"/> <job_chain_node state="SplitJobChain10:Job11" job="Job11" next_state="SetEventOK_11" error_state="!error"/> <job_chain_node state="SetEventOK_11" job="EventAdd" next_state="EndJobChain10" error_state="!error"/> <job_chain_node state="SplitJobChain10:Job12" job="Job12" next_state="SetEventOK_12" error_state="!error"/> <job_chain_node state="SetEventOK_12" job="EventAdd" next_state="EndJobChain10" error_state="!error"/> <job_chain_node state="SplitJobChain10:Job13" job="Job13" next_state="SetEventOK_13" error_state="SetEventNOK_13"/> <job_chain_node state="SetEventOK_13" job="EventAdd" next_state="EndJobChain10" error_state="!error"/> <job_chain_node state="SetEventNOK_13" job="EventAdd" next_state="!error" error_state="!error"/> <job_chain_node state="EndJobChain10" job="/sos/jitl/JobChainEnd" next_state="finish" error_state="!error"/> <job_chain_node state="finish"/> <job_chain_node state="!error"/> </job_chain>設定ファイルでは、JobChainSplitter で並列実行するジョブと、EventAddで生成するイベントをパラメータに設定します。
<?xml version="1.0" encoding="ISO-8859-1"?> <?xml-stylesheet type="text/xsl" href="scheduler_configuration_documentation.xsl"?> <settings> <job_chain name="JobChain10"> <order> <params/> <process state="SplitJobChain10"> <params> <param name="state_names" value="SplitJobChain10:Job11;SplitJobChain10:Job12;SplitJobChain10:Job13"/> </params> </process> <process state="SetEventOK_11"> <params> <param name="scheduler_event_add" value="add"/> <param name="scheduler_event_class" value="Report"/> <param name="scheduler_event_id" value="ev_Job11_JobRep60;ev_Job11_JobRep10;ev_Job11_Job31"/> </params> </process> <process state="SetEventOK_12"> <params> <param name="scheduler_event_add" value="add"/> <param name="scheduler_event_class" value="Report"/> <param name="scheduler_event_id" value="ev_Job12_JobRep10;ev_Job12_Job32"/> </params> </process> <process state="SetEventOK_13"> <params> <param name="scheduler_event_add" value="add"/> <param name="scheduler_event_class" value="Report"/> <param name="scheduler_event_id" value="ev_Job13_JobRep10;ev_Job13_Job33;ev_Job13_JobRep50"/> </params> </process> <process state="SetEventNOK_13"> <params> <param name="scheduler_event_add" value="add"/> <param name="scheduler_event_class" value="Report"/> <param name="scheduler_event_id" value="ev_Job13_Job33"/> </params> </process> </order> </job_chain> </settings>
JobChian31 - JobChain41
JobChain31からJobChain41の内容は以下のとおり。(各JobChainで数字は読み替え)
ジョブを実行後、EventAdd でイベントを生成しますが、JobChain42 だけは、イベント制御ファイルでイベントを生成するので、EventAdd はありません。
<?xml version="1.0" encoding="ISO-8859-1"?> <job_chain title="JobChain31"> <job_chain_node state="StartJobChain31" job="/sos/jitl/JobChainStart" next_state="Job31" error_state="!error"/> <job_chain_node state="Job31" job="Job31" next_state="SetEventOK_31" error_state="SetEventNOK_31"/> <job_chain_node state="SetEventOK_31" job="EventAdd" next_state="EndJobChain31" error_state="!error"/> <job_chain_node state="SetEventNOK_31" job="EventAdd" next_state="!error" error_state="!error"/> <job_chain_node state="EndJobChain31" job="/sos/jitl/JobChainEnd" next_state="finish" error_state="!error"/> <job_chain_node state="finish"/> <job_chain_node state="!error"/> </job_chain>設定ファイルでは、EventAddで生成するイベントをパラメータに設定します。
<?xml version="1.0" encoding="ISO-8859-1"?> <?xml-stylesheet type="text/xsl" href="scheduler_configuration_documentation.xsl"?> <settings> <job_chain name="JobChain31"> <order> <params/> <process state="SetEventOK_31"> <params> <param name="scheduler_event_add" value="add"/> <param name="scheduler_event_class" value="Report"/> <param name="scheduler_event_id" value="ev_Job31_Job41;ev_Job31_JobRep60;ev_Job31_JobRep30"/> </params> </process> <process state="SetEventNOK_31"> <params> <param name="scheduler_event_add" value="add"/> <param name="scheduler_event_class" value="Report"/> <param name="scheduler_event_id" value="ev_Job31_Job41"/> </params> </process> </order> </job_chain> </settings>
JobChainRep10-JobChainRep70
JobChainRep10からJobChainRep70の内容は以下のとおり。(各JobChainで数字は読み替え)
イベント生成は、イベント制御ファイルで実施します。
<?xml version="1.0" encoding="ISO-8859-1"?> <job_chain title="JobChainRep10"> <job_chain_node state="StartJobChainRep10" job="/sos/jitl/JobChainStart" next_state="JobRep10" error_state="!error"/> <job_chain_node state="JobRep10" job="JobRep10" next_state="EndJobChainRep10" error_state="!error"/> <job_chain_node state="EndJobChainRep10" job="/sos/jitl/JobChainEnd" next_state="finish" error_state="!error"/> <job_chain_node state="finish"/> <job_chain_node state="!error"/> </job_chain>設定ファイルはありません。
テストジョブ(Job10-Job41、JobRep10-JobRep70)
ジョブの内容は以下のとおり。全部同じです。
<?xml version="1.0" encoding="ISO-8859-1"?> <job order="yes"> <script language="shell"> <![CDATA[ echo "$SCHEDULER_JOB_NAME processed $SCHEDULER_ORDER_ID" echo "Current Timestamp: `date '+%Y-%m-%d %H:%M:%S'`" echo "Current Hostname: `uname -n`" echo "Current Username: `whoami`" exit 0 ]]> </script> <monitor name="process0" ordering="0"> <script language="perl"> <include file="./config/live/sample2/debug.pl"/> </script> </monitor> <run_time /> </job>
イベント生成ジョブ(EventAdd)
ジョブの内容は以下のとおり。並列実行できるように tasks を 10 にしています。
<?xml version="1.0" encoding="ISO-8859-1"?> <job order="yes" tasks="10"> <params/> <script language="java" java_class="sos.scheduler.job.JobSchedulerSubmitEventJob"/> <monitor name="configuration_monitor" ordering="0"> <script java_class="sos.scheduler.managed.configuration.ConfigurationOrderMonitor" language="java"/> </monitor> <monitor name="process0" ordering="0"> <script language="perl"> <include file="./config/live/sample2/debug.pl"/> </script> </monitor> <run_time /> </job>
イベント制御ファイル
イベント制御ファイルは、<JobScheduler_base>/config/events ディレクトリに作成します。
ファイル名には命名規則がありますが、今回は、Sample2Events.actions.xml にします。
内容は、以下のとおり。
<action>が図2のボックス1つになります。<events>に起動条件、<commands>に起動条件が成立したときに実行するコマンドを設定します。
<?xml version="1.0" encoding="UTF-8"?> <actions> <action name="JobChain31"> <events logic="and"> <event_group group="Report" logic="and" event_class="Report"> <event event_id="ev_Job11_Job31" event_title="Job11 OK" /> <event event_id="ev_Job21_Job31" event_title="Job21 OK" /> </event_group> </events> <commands> <command name="cmdJobChain31" scheduler_host="localhost" scheduler_port="4444"> <add_order job_chain="sample2/JobChain31" id="JobChain31" replace="yes" /> </command> <remove_event> <event event_id="ev_Job11_Job31" event_class="Report" /> </remove_event> <remove_event> <event event_id="ev_Job21_Job31" event_class="Report" /> </remove_event> </commands> </action> ~省略~ <action name="JobChain42"> <events logic="and"> <event_group group="Report" logic="and" event_class="Report"> <event event_id="ev_Job32_Job42" event_title="Job32 OK" /> </event_group> </events> <commands> <command name="cmdJobChain42" scheduler_host="localhost" scheduler_port="4444"> <add_order job_chain="sample2/JobChain42" id="JobChain42" replace="yes" /> </command> <remove_event> <event event_id="ev_Job32_Job42" event_class="Report" /> </remove_event> <add_event> <event event_id="ev_Job42_JobRep40" event_class="Report" /> </add_event> </commands> </action> ~省略~ <action name="JobChainRep70"> <events logic="and"> <event_group group="Report" logic="and" event_class="Report"> <event event_id="ev_JobRep10_JobRep70" event_title="JobRep10 OK" /> <event event_id="ev_JobRep20_JobRep70" event_title="JobRep20 OK" /> <event event_id="ev_JobRep30_JobRep70" event_title="JobRep30 OK" /> <event event_id="ev_JobRep40_JobRep70" event_title="JobRep40 OK" /> </event_group> </events> <commands> <command name="cmdJobChainRep70" scheduler_host="localhost" scheduler_port="4444"> <add_order job_chain="sample2/JobChainRep70" id="JobChainRep70" replace="yes" /> </command> <remove_event> <event event_id="ev_JobRep10_JobRep70" event_class="Report" /> </remove_event> <remove_event> <event event_id="ev_JobRep20_JobRep70" event_class="Report" /> </remove_event> <remove_event> <event event_id="ev_JobRep30_JobRep70" event_class="Report" /> </remove_event> <remove_event> <event event_id="ev_JobRep40_JobRep70" event_class="Report" /> </remove_event> </commands> </action> </actions>
動作確認
最初に上記設定をJOC、JIDで確認します。
各JobChainは、JOCで、下図のように見えます。
イベント制御ファイルは、定義した action が JIDの[Event Handler]タブで、下図のように見えます。
まず、JOCで、JobChain10 を実行します。
下図は、実行中の状態です。
JobChain10 の実行終了後、debug.log でジョブの実行状況を見ると以下のとおり。
イベントの起動条件が成立したので、JobChainRep10 は自動的に実行されています。
2014-09-22 11:50:16 - START - JOB=sample2/Job10 - ORDER_ID=556 2014-09-22 11:50:16 - END - JOB=sample2/Job10 - ORDER_ID=556 2014-09-22 11:50:21 - START - JOB=sample2/Job13 - ORDER_ID=556_SplitJobChain10:Job13 2014-09-22 11:50:21 - START - JOB=sample2/Job11 - ORDER_ID=556_SplitJobChain10:Job11 2014-09-22 11:50:21 - START - JOB=sample2/Job12 - ORDER_ID=556_SplitJobChain10:Job12 2014-09-22 11:50:21 - END - JOB=sample2/Job12 - ORDER_ID=556_SplitJobChain10:Job12 2014-09-22 11:50:21 - END - JOB=sample2/Job11 - ORDER_ID=556_SplitJobChain10:Job11 2014-09-22 11:50:21 - END - JOB=sample2/Job13 - ORDER_ID=556_SplitJobChain10:Job13 2014-09-22 11:50:25 - START - JOB=sample2/EventAdd - ORDER_ID=556_SplitJobChain10:Job11 2014-09-22 11:50:25 - START - JOB=sample2/EventAdd - ORDER_ID=556_SplitJobChain10:Job13 2014-09-22 11:50:25 - START - JOB=sample2/EventAdd - ORDER_ID=556_SplitJobChain10:Job12 2014-09-22 11:50:31 - END - JOB=sample2/EventAdd - ORDER_ID=none 2014-09-22 11:50:31 - END - JOB=sample2/EventAdd - ORDER_ID=none 2014-09-22 11:50:31 - END - JOB=sample2/EventAdd - ORDER_ID=none 2014-09-22 11:50:34 - START - JOB=sample2/JobRep10 - ORDER_ID=JobChainRep10 2014-09-22 11:50:34 - END - JOB=sample2/JobRep10 - ORDER_ID=JobChainRep10この時点でのイベントの状況は、JID で確認できます。
JIDの[Event Handler]タブでは、各アクションごとのイベントの状況(ステータス、生成時間、有効期限)を確認できます。
下図の例では、JobChain10 がイベントの"ev_Job12_Job32" を生成したので、[EventStatus]欄が "active" になっています。後1つのイベントが生成されたら、JobChain32 は自動的に実行されます。
JIDの[Events]タブでは、現在、存在しているイベントの一覧を確認できます。
[Job]、[Job Chain]欄が空白なのは、イベント制御ファイルで生成を定義したイベントです。
最後に、JobChain20 を実行します。これで、残りのジョブは全部実行されます。
下図は実行中の画面です。
debug.log は以下のとおり。残りのジョブが全部実行されています。
2014-09-22 12:06:30 - START - JOB=sample2/Job20 - ORDER_ID=565 2014-09-22 12:06:30 - END - JOB=sample2/Job20 - ORDER_ID=565 2014-09-22 12:06:35 - START - JOB=sample2/Job23 - ORDER_ID=565_SplitJobChain20:Job23 2014-09-22 12:06:35 - END - JOB=sample2/Job23 - ORDER_ID=565_SplitJobChain20:Job23 2014-09-22 12:06:35 - START - JOB=sample2/Job12 - ORDER_ID=565_SplitJobChain20:Job22 2014-09-22 12:06:35 - START - JOB=sample2/Job21 - ORDER_ID=565_SplitJobChain20:Job21 2014-09-22 12:06:35 - END - JOB=sample2/Job12 - ORDER_ID=565_SplitJobChain20:Job22 2014-09-22 12:06:35 - END - JOB=sample2/Job21 - ORDER_ID=565_SplitJobChain20:Job21 2014-09-22 12:06:37 - START - JOB=sample2/EventAdd - ORDER_ID=565_SplitJobChain20:Job23 2014-09-22 12:06:38 - START - JOB=sample2/EventAdd - ORDER_ID=565_SplitJobChain20:Job22 2014-09-22 12:06:38 - START - JOB=sample2/EventAdd - ORDER_ID=565_SplitJobChain20:Job21 2014-09-22 12:06:44 - END - JOB=sample2/EventAdd - ORDER_ID=none 2014-09-22 12:06:44 - END - JOB=sample2/EventAdd - ORDER_ID=none 2014-09-22 12:06:44 - END - JOB=sample2/EventAdd - ORDER_ID=none 2014-09-22 12:06:49 - START - JOB=sample2/Job33 - ORDER_ID=JobChain33 2014-09-22 12:06:49 - END - JOB=sample2/Job33 - ORDER_ID=JobChain33 2014-09-22 12:06:51 - START - JOB=sample2/EventAdd - ORDER_ID=JobChain33 2014-09-22 12:06:52 - START - JOB=sample2/Job31 - ORDER_ID=JobChain31 2014-09-22 12:06:52 - END - JOB=sample2/Job31 - ORDER_ID=JobChain31 2014-09-22 12:06:55 - START - JOB=sample2/EventAdd - ORDER_ID=JobChain31 2014-09-22 12:06:57 - START - JOB=sample2/Job32 - ORDER_ID=JobChain32 2014-09-22 12:06:57 - END - JOB=sample2/Job32 - ORDER_ID=JobChain32 2014-09-22 12:06:57 - END - JOB=sample2/EventAdd - ORDER_ID=none 2014-09-22 12:07:01 - START - JOB=sample2/Job43 - ORDER_ID=JobChain43 2014-09-22 12:07:01 - END - JOB=sample2/Job43 - ORDER_ID=JobChain43 2014-09-22 12:07:04 - START - JOB=sample2/Job41 - ORDER_ID=JobChain41 2014-09-22 12:07:04 - END - JOB=sample2/Job41 - ORDER_ID=JobChain41 2014-09-22 12:07:07 - START - JOB=sample2/JobRep30 - ORDER_ID=JobChainRep30 2014-09-22 12:07:07 - END - JOB=sample2/JobRep30 - ORDER_ID=JobChainRep30 2014-09-22 12:07:09 - START - JOB=sample2/JobRep20 - ORDER_ID=JobChainRep20 2014-09-22 12:07:09 - END - JOB=sample2/EventAdd - ORDER_ID=none 2014-09-22 12:07:09 - END - JOB=sample2/JobRep20 - ORDER_ID=JobChainRep20 2014-09-22 12:07:12 - START - JOB=sample2/JobRep70 - ORDER_ID=JobChainRep70 2014-09-22 12:07:12 - END - JOB=sample2/JobRep70 - ORDER_ID=JobChainRep70 2014-09-22 12:07:15 - START - JOB=sample2/JobRep50 - ORDER_ID=JobChainRep50 2014-09-22 12:07:15 - END - JOB=sample2/JobRep50 - ORDER_ID=JobChainRep50 2014-09-22 12:07:17 - START - JOB=sample2/Job42 - ORDER_ID=JobChain42 2014-09-22 12:07:17 - END - JOB=sample2/Job42 - ORDER_ID=JobChain42 2014-09-22 12:07:20 - START - JOB=sample2/JobRep60 - ORDER_ID=JobChainRep60 2014-09-22 12:07:20 - END - JOB=sample2/JobRep60 - ORDER_ID=JobChainRep60 2014-09-22 12:07:22 - START - JOB=sample2/JobRep40 - ORDER_ID=JobChainRep40 2014-09-22 12:07:22 - END - JOB=sample2/JobRep40 - ORDER_ID=JobChainRep40