[CentOS6][SOS JobScheduler] イベントハンドラの使用例 - マージ&スプリット


Create: 2013/03/22
LastUpdate: 2013/05/24
[ メニューに戻る ]

下図の環境を使用します。
環境の詳細を知りたい場合は、メニューに戻って構築手順を参照してください。
手順については、「JobScheduler Events(PDF)」を参考にしました。


JobChain では、シーケンシャルなジョブの連携しか定義できませんでしたが、
イベントを利用することで下図のような複雑な条件のジョブ連携が可能になります。
(図:JobSchedulerEventマニュアルから引用)

このジョブ連携をXML形式のイベントハンドラを使って実行してみます。
定義するジョブは以下のとおり。今回は、全部、Host-A で実行することにします。
  • Job1 ~ Job9 は、StandaloneJob で定義します。 
  • Job80 ~ Job82 は、OrderJob にして、JobChainに定義します。
イベントハンドラで実行するのは、Job5 以降です。
実行順序は以下のように流れなります。
  1. Job1 ~ Job4 を個別に実行する
  2. イベントハンドラが、Job1 ~ Job4 で生成したイベントを検知し、Job5 を実行する
  3. イベントハンドラが、Job5 で生成したイベントを検知し、Job6 ~ Job9 と JobChain(Job80~Job81) を実行する
今回、ジョブの定義ではJOEは使用せず、直接XMLファイルを作成しています。
ジョブ関連の定義を格納するホットフォルダとイベントハンドラを格納するディレクトリは以下のとおり
[ホットフォルダ]
/home/jobs/sos-berlin.com/jobscheduler/scheduler/config/live/test2

[イベントハンドラ格納ディレクトリ]
/home/jobs/sos-berlin.com/jobscheduler/scheduler/config/events

1.イベントハンドラの定義


今回は、以下のファイル名で XML形式のイベントハンドラを作成します。
test2.actions.xml
内容は、以下のとおり。"BeforeJob5" と "AfterJob5" の2つのアクションを定義します。
<?xml version="1.0" encoding="UTF-8"?>
<actions>
  <action name="BeforeJob5">
    <events logic="and">
      <event_group group="pre" logic="and" event_class="pre">
        <event event_id="1" job_name="job1" />
        <event event_id="2" job_name="job2" />
        <event event_id="3" job_name="job3" />
        <event event_id="4" job_name="job4" />
      </event_group>
    </events>
    <commands>
      <command name="command_11" scheduler_host="localhost" scheduler_port="4444">
        <start_job job="test2/job5" />
      </command>
      <remove_event>
       <event event_class="pre" />
      </remove_event>
    </commands>
  </action>
  <action name="AfterJob5">
    <events>
      <event_group group="post" event_class="post" logic="and">
        <event event_id="5" job_name="job5" />
      </event_group>
    </events>
    <commands>
      <command name="command_21" scheduler_host="localhost" scheduler_port="4444">
        <start_job job="test2/job6" />
      </command>
      <command name="command_22" scheduler_host="localhost" scheduler_port="4444">
        <start_job job="test2/job7" />
      </command>
      <command name="command_23" scheduler_host="localhost" scheduler_port="4444">
        <start_job job="test2/job9" />
      </command>
      <command name="command_24" scheduler_host="localhost" scheduler_port="4444">
        <add_order job_chain="test2/job_chain1" replace="yes" id="1" />
      </command>
      <remove_event>
       <event event_class="post" />
      </remove_event>
    </commands>
  </action>
</actions>
"BeforeJob5" は、Job1 ~ Job4 が終了時に生成するイベント(pre)を全部検知したら、Job5 を実行し、イベント(pre)を削除します。
"AfterJob5" は、Job5 が終了時に生成するイベント(post)を検知したら、Job6 ~ Job9 と JobChain(Job80 ~ Job82) を実行し、イベント(post)を削除します。

2.ジョブ、JobChain の定義


テスト用の簡単なシェルスクリプトを実行するジョブとJobChainを定義します。全部、Host-Aで実行します。
今回、ホットフォルダに作成するファイルは、以下のとおり。
$ ls /home/jobs/sos-berlin.com/jobscheduler/scheduler/config/live/test2
Host-A.process_class.xml  job3.job.xml  job6.job.xml   job81.job.xml  job_chain1.job_chain.xml
job1.job.xml              job4.job.xml  job7.job.xml   job82.job.xml
job2.job.xml              job5.job.xml  job80.job.xml  job9.job.xml

2.1.プロセスクラスの定義


Host-Aでの実行を指示する peocess_class を作成します。ファイル名は以下のとおり。
Host-A.process_class.xml
内容は以下のとおり。
<?xml version="1.0" encoding="ISO-8859-1"?>
<process_class  max_processes="64" remote_scheduler="192.168.1.82:4444"/>
"192.168.1.82" は Host-A のIPアドレスです。

2.2.Job1~Job5の定義


イベントを生成する StandalobeJob を作成します。ファイル名は以下のとおり。
job1.job.xml  job2.job.xml  job3.job.xml  job4.job.xml  job5.job.xml 
内容は以下のとおり。
<?xml version="1.0" encoding="ISO-8859-1"?>
<job  process_class="Host-A">
    <params>
      <param name="scheduler_event_id" value="1"/>
      <param name="scheduler_event_class" value="pre"/>
    </params>
    <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="create_event" ordering="0">
      <script language="java" java_class="sos.scheduler.job.JobSchedulerSubmitEventMonitor"/>
    </monitor>
    <run_time />
</job>
赤字部分のパラメータはジョブごとに以下の値を設定します。
Job1 Job2 Job3 Job4 Job5
scheduler_event_class pre pre pre pre post
scheduler_event_id 1 2 3 4 5

2.3.Job6~Job9の定義


シェルスクリプトを実行するだけのStandaloneJobを作成します。ファイル名は以下のとおり。
job6.job.xml  job7.job.xml  job9.job.xml 
内容は以下のとおり。
<?xml version="1.0" encoding="ISO-8859-1"?>
<job  process_class="Host-A">
    <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>
    <run_time />
</job>

2.4.Job80~Job82とJobChainの定義

シェルスクリプトを実行するだけのOrderJobを作成します。ファイル名は以下のとおり。
job80.job.xml  job81.job.xml  job82.job.xml 
内容は以下のとおり。
<?xml version="1.0" encoding="ISO-8859-1"?>
<job  process_class="Host-A" 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>
    <run_time />
</job>
この OrderJob を順番に実行するJobChain を作成します。ファイル名は以下のとおり。
job_chain1.job_chain.xml
内容は以下のとおり。
<?xml version="1.0" encoding="ISO-8859-1"?>
<job_chain  orders_recoverable="yes" visible="yes">
    <job_chain_node  state="step1" job="job80" next_state="step2" error_state="error"/>
    <job_chain_node  state="step2" job="job81" next_state="step3" error_state="error"/>
    <job_chain_node  state="step3" job="job82" next_state="success" error_state="error"/>
    <job_chain_node  state="success"/>
    <job_chain_node  state="error"/>
</job_chain>

3.動作確認


今回は、JOCを使用せずに、コマンドラインからジョブを即時実行します。
Managerサーバに jobs ユーザでログインして、以下のようにコマンドを実行し、4つのジョブを実行します。
$ cd ~/sos-berlin.com/jobscheduler/scheduler/scheduler_home/bin
$ ./jobscheduler.sh command "<start_job job='test2/job1'/>"
$ ./jobscheduler.sh command "<start_job job='test2/job2'/>"
$ ./jobscheduler.sh command "<start_job job='test2/job3'/>"
$ ./jobscheduler.sh command "<start_job job='test2/job4'/>"
XMLコマンドの詳細は、「Reference Documentation」を参照してください。
上記コマンドの実行結果は以下のように表示されます。
$ ./jobscheduler.sh command "<start_job job='test2/job1'/>"
<?xml version="1.0" encoding="ISO-8859-1"?>
<spooler><answer time="2013-03-24 08:34:20.465"><ok><task job="/test2/job1" id="3636" task="3636" state="none" name="" enqueued="2013-03-24 08:34:20.470" start_at="2013-03-24 08:34:20.466" steps="0" log_file="/home/jobs/sos-berlin.com/jobscheduler/scheduler/logs/scheduler-2013-03-22-121442.scheduler.log" force_start="yes"><log level="info"/></task></ok></answer></spooler>
Job1~Job4 までの実行が完了したら、JOCでイベントハンドラの実行結果を確認します。
下図のように sceduler_event_service の ORDER HISTORY を見ます。


ORDER HISTORY のIDが 615 ~ 619 の結果が、今回のイベントハンドラの実行結果です。
それぞれ以下のように結果を見ることができます。
  • 615 ・・・ Job1 が生成したイベントを検知して、イベントハンドラが起動。しかし、一致する条件のアクションなし。
  • 616 ・・・ Job2 が生成したイベントを検知して、イベントハンドラが起動。しかし、一致する条件のアクションなし。
  • 617 ・・・ Job3 が生成したイベントを検知して、イベントハンドラが起動。しかし、一致する条件のアクションなし。
  • 618 ・・・ Job4 が生成したイベントを検知して、イベントハンドラが起動。"BeforeJob5" アクションを実行した。
  • 619 ・・・ Job5 が生成したイベントを検知して、イベントハンドラが起動。"AfterJob5" アクションを実行した。
sceduler_event_service がデバッグ情報を出力するように 設定していると 618 のログに、以下のような記録を見ることができます。これで、"BeforJob5"アクションに定義きたコマンドを実行していることがわかります。
.. looking for special event handler for:  (\..*)?\.actions\.xml$
.. analysing action event handler: /home/jobs/sos-berlin.com/jobscheduler/scheduler/config/events/test2.actions.xml
.... checking action BeforeJob5
.... added action:BeforeJob5
.. command was added
....name=command_11
....scheduler_host=localhost
....scheduler_port=4444
.. remove_event was added
.... checking action AfterJob5
619 のログは以下のとおり。
.. looking for special event handler for:  (\..*)?\.actions\.xml$
.. analysing action event handler: /home/jobs/sos-berlin.com/jobscheduler/scheduler/config/events/test2.actions.xml
.... checking action BeforeJob5
.... checking action AfterJob5
.... added action:AfterJob5
.. command was added
....name=command_21
....scheduler_host=localhost
....scheduler_port=4444
.. command was added
....name=command_22
....scheduler_host=localhost
....scheduler_port=4444
.. command was added
....name=command_23
....scheduler_host=localhost
....scheduler_port=4444
.. command was added
....name=command_24
....scheduler_host=localhost
....scheduler_port=4444
.. remove_event was added
一応、イベントがちゃんと削除されているか、確認してみます。
以下のようにコマンドを実行して、"0" と表示されたらOKです。
$ cd ~/sos-berlin.com/jobscheduler/scheduler/scheduler_home/bin
$ ./jobscheduler_event.sh -e pre -w check -h localhost -p 4444
0 
$ ./jobscheduler_event.sh -e post -w check -h localhost -p 4444
0 
ジョブの実行結果を、 JIDのダッシュボード で確認すると、下図のとおり、全部正常終了しています。


ちなみに、 JIDを統合管理コンソール に設定すると、イベントの有無や、イベントハンドラの状況をGUIで確認できるようになります。