November 24, 2014

Laravel 5のartisan schedule:runコマンドで定期実行するタスクをPHP側で管理する

Laravel 5は現在開発中です。正式リリース版では、当記事の内容と異なる可能性があります。

Laravel 5では、定期実行されるタスク(要はcron)を、PHP側で一元的に管理できるようになるみたいです。正確には、1 cron設定でNタスクを管理できる。といった感じでしょうか。

尚、この機能は、以下のライブラリに依存しているようです。
https://github.com/mtdowling/cron-expression

細かな書き方などは、以下がとても参考になりました。
http://laravel-news.com/2014/11/laravel-5-scheduler/
http://mattstauffer.co/blog/laravel-5.0-event-scheduling

以下、簡単なサンプルです。

適当なコマンドクラスを作ります。内容は、実行された時刻を標準出力するだけです。
$ php artisan make:console ScheduleExampleCommand --command=schedule:example
app/Console/Commands/ScheduleExampleCommand.php
<?php namespace App\Console\Commands;

use Illuminate\Console\Command;

class ScheduleExampleCommand extends Command {

    /**
     * The console command name.
     *
     * @var string
     */
    protected $name = 'schedule:example';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Command schedule:example';

    public function fire()
    {
        echo sprintf('%s fired at %s', $this->name, date('Y-m-d H:i:s'));
    }
}
app/Console/Kernel.php の protected $commands に、作成したコマンドクラスを登録します。
<?php namespace App\Console;

use Exception;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;

class Kernel extends ConsoleKernel {

    /**
     * The Artisan commands provided by your application.
     *
     * @var array
     */
    protected $commands = [
        'App\Console\Commands\ScheduleExampleCommand',
    ];
同様に、app/Console/Kernel.php のschedule()メソッドでスケジューリングします。
    protected function schedule(Schedule $schedule)
    {
        $schedule->command('schedule:example')
            ->cron('*/1 * * * * *')
            ->sendOutputTo(storage_path('logs/schedule.example.log'));
    }
cron()メソッドに、お馴染みの書式で実行間隔を指定しています。今回は、1分毎です。5分毎とかならcron()ではなくeveryFiveMinutes()とかでOKです。

参考: https://github.com/laravel/framework/blob/master/src/Illuminate/Console/Scheduling/Event.php

また、sendOutputTo()メソッドで、標準出力の保存先を指定しています。実行結果メールの送信先を指定するemailOutputTo()とかもあるみたいです。

php artisan schedule:run コマンドで、正しく実行されるか確認してみます。
$ php artisan schedule:run
Running scheduled command: /usr/bin/php5 artisan schedule:example > /home/vagrant/Code/example/storage/logs/schedule.example.log 2>&1 &
storage/logs/schedule.example.log が正しく出力されていれば成功です。どうも、今現在は追記式ではないようですね。実行の度に同一のログファイル名を出力先に指定すれば、毎回、新たなログファイルが生成されてしまいます。この辺は、そのうち追記式もできるようになる気がする。(根拠は無い。)

最後に php artisan schedule:run コマンドをcron設定してみます。Homesteadで確認しています。
$ sudo vim /etc/cron.d/schedule-example

# 以下を記述
*/1 * * * * vagrant /usr/bin/php /home/vagrant/Code/example/artisan schedule:run
storage/logs/schedule.example.log が毎分正しく更新されれば成功です。
schedule:example fired at 2014-11-23 16:43:21
cron設定は数が増えてくると、いつどのようなタスクが実行されているか把握するのが面倒な時がありますが、この方法なら一目瞭然に管理できそうですね。

No comments:

Post a Comment