hirokws/strivejobs

Job controlle system.

0.1.1 2013-09-23 11:26 UTC

README

Job management with commands. Without Laravel queue facility.

But now making. So please wait a while.

コマンドとAPIによるジョブ管理Laravel4パッケージ。仕事を時間的に分散させて実行する目的のジョブ管理システムです。

只今、作成中です。GitHubに自分で使用するために置いています。アルファ版です。

Overview

1.ジョブクラスの登録

StriveJobs\StriveJobsInterfaceを実装し、StriveJobs\BaseJobClassを拡張したクラスを作成する。

<?php

use StriveJobs\StriveJobsInterface;
use StriveJobs\BaseJobClass;

class BulkMail extends BaseJobClass implements StriveJobsInterface
{

    public function getDescription()
    {
        return 'このジョブクラスの説明'; // listコマンドで標示
    }

    public function getName()
    {
        return 'BulkMail'; // ジョブの名前
    }

    public function doRegistered( $data ) // do+ステータスのメソッドが呼び出される
    {
        $this->message = 'おめでとう!'; // 表示メッセージの設定
        $this->setTerminated(); // set+ステータスで、ステータス変更
        return true; // 呼び出し元に、実行の成功を通知
    }

    public function doTerminated( $data ) // ステータスterminatedはジョブ終了
    {
        $this->message = '残念!切腹!';
        $this->harakiri(); // この実行ジョブを削除
        return true;
    }

    public function doDefault( $data ) // メソッド未定義の場合はこれが呼び出される
    {
        $this->message = '残念!'; // 呼び出し元にメッセージを渡す
        return false; // 呼び出し元に、実行の失敗を通知
    }

}

2.ジョブクラスのインスタンスを登録する。

SJ::registerJobClass( array( new BulkMail ) );
SJ::registerJobClass( array( new MonthlyJob ) );
SJ::registerJobClass( array( new WeeklyJob ) );
...

3.コマンドとAPIが使用できるようになる。

php artisan sjob:list # 登録したジョブクラス表示
php artisan sjob:register BulkMail --comment "8月29日送信" # 新ジョブ登録
php artisan sjob:do 7 # 登録済みジョブ実行

4.多分、ジョブの起動はcronなどのコマンドから使用する。

php /home/my/project/artisan sjob:auto # 一番古いterminated以外のジョブを一つ実行

5.コマンドと同じようにAPIからも操作できるので、Webページからも管理可能。

インストール

1.`require "hirokws/strivejobs"、もしくはcomposer.jsonに以下の行を登録し、updateを実行。

"register": {
    "hirokws/strivejobs" : "dev-master"
}

2.app/config/app.phpへサービスプロバイダーを登録する。

'StriveJobs\StriveJobsServiceProvider',

3.APIを使用する場合は、エイリアスも登録すると便利。(登録せずとも、App::make('StriveJobs\\StriveJobs')でインスタンスを取得可能)

'SJ' => 'StriveJobs\StriveJobsFacade',

4.マイグレーションを実行する。事前にデータベースの設定が必要。

php artisan migrate --package hirokws/strivejobs

5.設定ファイルをローカルにコピーする。(app/config/packages/hirokws/stirivejobsにconfig.phpが作成される。)

php artisan config:package hirokws/strivejobs

6.必要に応じ、設定ファイルでコマンド名、サブコマンド名を変更する。

7.テーブルをtruncateするresetコマンドのパスワードのハッシュを設定する。ハッシュ値はresetコマンドで生成する。(以下はデフォルトのコマンド名、sjobの場合)

php artisan sjob:reset -?
StriveJobsとは?

VPSも含め、サーバーを自前で立てる場合、もしくは(PHPから見て)外部のキュー、SNSサービスなどのリソースを豊富に利用する場合であれば、この様なジョブ管理は必要ないでしょう。(いや、いるかも知れませんね。)

Web上のサービスを利用するにしても、無料使用枠に軽く収まってしまう程度の、小さなサービスを同時に2つ思いつきました。必要な機能の一部をこうした外部サービスに依存するにしても、処理を時間的に分散させるため、自動起動するジョブの管理が必要になりました。どうせなら、パッケージで作成し、2システム共通で利用しようと作成し始めたのが、このStriveJobsです。

パッケージ名はあの有名だった人と似たような響きの言葉を選びました。"strive jobs"で「仕事を求め、もしくは仕事しようと努力する」という意味です。仕事と格闘している日本人の現状をほのかに織り込んだ名前です。ちなみに私はLinuxユーザーです。

What for?

主な目的はバルクメール配信などを共有サーバーから行うために作成しました。サーバーのリソースを連続して使用する可能性のある作業を時間的に分割して行うための補助パッケージです。 共有サーバーでは、リソースの縛りがあります。たとえPHPのCLIの実行時間が無制限であろうと、連続した作業をダラダラと続けていると、どこかで制限に引っかかってしまいます。通常はCPUの使用%であったり、プロセスの実行時間で引っかかります。そのため、安全圏内で動作させる工夫が必要です。

そして最近は、共有サーバー専用Linuxと銘打ったOSも存在し、仮想化の技術を応用して、各ユーザーの利用資源を管理しています。つまりCPUの割り当て個数や使用メモリを制限しているわけです。他のユーザーからの影響を受けないため「安全」であると、宣伝されます。しかし、CPUの割り当てが一つで、そこに長時間負荷がかかる「裏」の仕事をさせてしまえば、表のサイトレスポンスに多少なりとも影響が生まれてしまいます。

処理を時間的に分けるには、その処理単位を管理しなくてはなりません。(分けなくても、時間がかかる処理を制限のある環境で連続動作させるなら、何らかの管理方法が必要になるでしょう。)何らかの原因で実行が途中で停止したり、異常終了した場合には、そのリカバリー処理も必要になります。

余りにシリアスであれば、そのシステム専用に真面目に設計し、作りこむ必要があります。しかし、共有サーバー上で動作させる、バルクメールの送信程度であれば、処理単位毎に状態管理し、それに応じて処理を実行する程度の処理ができれば、事足ります。

また、管理するためのコマンドツールを毎回作りこむのも馬鹿らしいですね。そのために、コマンド群も開発しました。

そうした訳で、PHPプログラムのひとかたまりの処理単位をジョブとして管理するパッケージです。

ジョブクラス

ジョブはジョブクラスとして記述します。StriveJobs\StriveJobsInterfaceを実装し、StriveJobs\BaseJobClassを拡張してください。

ジョブクラスのインスタンスをサービスプロバイダーやapp/start/global.phpなどで、登録してください。APIクラスのStriveJobs\StriveJobsをSJのエイリアスで登録済みの場合、BulkMailジョブクラスを登録するには、次の形式になります。

SJ::registerJobClass( array( new BulkMail ) );

もしくは、インスタンスを取得し、登録する方法も取れます。

App::make('StriveJobs\\StriveJobs')->registerJobClass( array( new BulkMail ) );

APIを呼び出すか、registerコマンドでジョブを登録します。ジョブにはどの実行段階にあるかを表すステータスがあり、登録時はregisteredになります。

ジョブの完了状態はterminatedで表します。それ以外のステータスはお好きに作成できます。

ジョブに(通常はcronから)起動がかかると、ジョブクラス内の'do'+'ステータス'メソッドが実行されます。該当するメソッドがクラスに存在しない場合、'doDefault'メソッドが呼び出されます。

ジョブクラス内で使用できるプロパティとメソッドは、後述の「StriveJobs\BaseJobClass」をご覧ください。

ステータス

ステータスは自動では変化しません。ジョブクラス内の呼び出しメソッド内で変更します。

ステータスが変更されても、対応するメソッドは自動的に呼び出されません。次回のジョブが起動された時に、その時点のステータスに対応するジョブが呼び出されます。

注意

StriveJobsは、ジョブの排他制御を行いません。つまり、異なった方法で起動されたり、前回のジョブが終了していないのに、起動がかけられたりすることで、同じジョブが同時に複数プロセスで起動される可能性があります。必要であれば、ジョブ内で制御してください。(もしくは以下のように運用でダブリを避けましょう。)

推定される使用方法(利用シナリオ)
  1. ジョブの登録はWebからAPIを通じて登録するか、コマンドで行う。もしくはcronにより、定期的に登録される。
  2. ジョブの起動は管理者一人がWebもしくはコマンドから起動するか、cronより定期的に自動的に起動するなど、一箇所からのみ行う。
  3. 一回のautoコマンドでは、起動するジョブは一つに指定する。(デフォルト)
  4. ジョブ内では実行時間をチェックし、長くなり過ぎないように制御する。
  5. changeコマンドはテスト時、および非常用、原則はジョブ内部でステータスを変更する。

運用により常に1ジョブだけが走るようにすることで、ジョブの排他制御を避けることができます。(2,3)

コマンド

Laravel4では、コマンドのベースとしてSymfonyライブラリーを利用しているため、コマンド名とサブコマンド名を組み合わせることができます。

デフォルトのコマンド名はsjobです。コマンド名、サブコマンド名共に、設定ファイルで変更可能です。

--quiet(-q)オプションで出力を抑制できます。cronから起動する場合など、出力を避けたい場合に便利です。書くサブコマンドで使用できるオプションは--helpで確認できます。

以下の説明はサブコマンドの説明となります。名前はデフォルト値で説明しています。

register(登録)サブコマンド

ジョブを登録します。

サンプル

php artisan sjob:register BulkMail

BulkMailのジョブクラス名をジョブとして登録します。コメント・引数は空になります。起動間隔はデフォルトの0分です。

php artisan sjob:register BulkMail 101 200  -c "10月10日起動2回目" - i 60

コメントと引数を指定したサンプルです。起動間隔を60分に設定しています。

コマンド

php artisan sjob:register [-c|--comment[="..."]] [-i|--interval[="..."]] job [argument1] [argument2] [argument3] [argument4] [argument5]

引数とオプション

job ジョブクラス名。ジョブクラスのgetNameで返される値を指定する。 argument1 引数(任意) argument2 引数(任意) argument3 引数(任意) argument4 引数(任意) argument5 引数(任意) --comment(-c) コメント(任意) --interval(-i) 起動間隔分数(任意、デフォルト0分)

説明

起動されるジョブクラスを表す名前を指定し、ジョブを登録します。ステータスは'registered'になります。登録後、そのIDが表示されます。

引数のargument1〜5は以下の形式で、ジョブクラス内のステータスに対応したジョブメソッドに渡されます。

array(
    'arg1'=>'argument1の引数',
    'arg2'=>'argument1の引数',
    ...
    'arg5'=>'argument5の引数',
);

このシステムには自分で起動をかけるような機能は付いていません。

起動間隔はautoコマンドより起動がかけられた場合に、指定した分数を経過しているかチェックし、時間を過ぎていた場合のみ起動されます。

デフォルトの0分の場合、cronなどで起動をかけるたび、無条件で起動します。共有サーバーの場合、cronの起動間隔にも制限のある場合もあるのですが、理想的には毎分起動に設定し、ジョブの起動間隔は、登録時にこのコマンドで設定する方法も取れます。

show(ジョブ表示)サブコマンド

登録済みのジョブを表示します。

サンプル

php artisan sjob:show

全件を最新順に表示します。

php artisan sjob:show terminated --oldest -take 10

ステータスがterminatedのジョブを最新順に10件表示します。

コマンド

php artisan sjob:show [-t|--take[="..."]] [-o|--oldest] [status]

引数とオプション status 指定されたステータスのジョブのみ表示します。(任意) --take (-t) 指定された件数表示します。(任意) --oldest (-o) 古いジョブの順番に表示します。(任意)

説明

登録済みのジョブを表示します。デフォルトは最新順で全件表示します。

do(ジョブ起動)サブコマンド

登録済みのジョブを起動します。

サンプル

php artisan sjob:do 51

ジョブIDが51番のジョブを起動します。

コマンド

php artisan sjob:do id

引数とオプション

id 実行するジョブのIDを一つ指定します。

説明

指定されたIDのジョブを起動します。

このコマンドによる起動では、登録時指定した起動間隔分数は無視され、必ず起動がかけられます。

ただし、次回の起動時間は、起動間隔分数進められます。

auto(自動起動)サブコマンド

ルールに従い、登録済みのジョブを起動します。

サンプル

コマンド 引数とオプション 説明

change(ステータス変更)サブコマンド

ステータスを変更します

サンプル

コマンド 引数とオプション 説明

sweep(終了ジョブ削除)サブコマンド

終了状態のジョブを削除します。

サンプル

コマンド 引数とオプション 説明

reset(管理テーブルリセット)サブコマンド

ジョブ管理テーブルをリセットします。

サンプル

コマンド 引数とオプション 説明

list(登録ジョブクラス表示)サブコマンド

登録済みジョブクラスを一覧表示します。

サンプル

コマンド 引数とオプション 説明

API

StriveJobs\StriveJobsクラスをご覧ください。

StriveJobs\BaseJobClass プロパティ
  • striveJobs : StriveJobs\StriveJobsクラスのインスタンス
  • jobId : ジョブの登録ID
  • status : ジョブのステータス
  • comment : ジョブのコメント
setステータス名

ステータスを変更します。

setステータス名()

メソッド名のsetに続く名前に、ステータスを変更します。

例えば、setPhase1であれば、ステータスはphase1になります。

ステータスを変更しても、自動的に「doステータス」メソッドは呼び出されません。次回の起動時に呼び出されることになります。もしくは必要であれば、手動で呼び出してください。

putArguments( $data )

doステータスメソッドが自動的に呼び出される場合に渡される引数を保存します。

引数は配列です。

引数をこのメソッドで変更しない限り、自動的に元の配列が渡され続けます。

getComment()

コメントを取得します。

putComment( $comment )

コメントを保存します。コメントはshowコマンドで標示されます。

removeMe()

起動しているジョブの登録を削除します。

killMe()とharakiri()は、このメソッドの別名です。

setMessage( $message )

メッセージを保存します。このメッセージはコマンドから起動された場合は端末で表示されます。APIから起動されている場合は、APIインスタンスのlastMessageプロパティとしてセットされます。