今天体验了 Laravel 中的定时任务功能,体验到了这个框架对于定时任务处理的优雅和方便,使用起来很方便,通过预定义的方法设置不同的执行周期,接下来说一下基本的定时任务的使用。
开发环境:Homestead;
框架版本:Laravel5.5;
打开框架的 app/Console/Kernel.php 文件,内容如下:
<?php
namespace App\Console;
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 = [
];
/**
* Define the application's command schedule.
*
* @param \Illuminate\Console\Scheduling\Schedule $schedule
* @return void
*/
protected function schedule(Schedule $schedule)
{
// $schedule->command('inspire')
// ->hourly();
}
/**
* Register the commands for the application.
*
* @return void
*/
protected function commands()
{
$this->load(__DIR__.'/Commands');
require base_path('routes/console.php');
}
}
其中 schedule() 方法是用于定义定时任务的执行,可使用 call() 和 command() 方法进行定义,call() 方法主要用于定义包含简单业务逻辑的任务,command() 方法主要执行 Command 类中定义的业务逻辑,适合更复杂的业务逻辑。接下来,分别使用这两个方法进行举例,实现每分钟打印信息到 Log 中的功能。
call() 实现:
<?php
namespace App\Console;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
use Illuminate\Support\Facades\Log;
class Kernel extends ConsoleKernel
{
...
protected function schedule(Schedule $schedule)
{
//每分钟打印到log中
$schedule->call(function () {
Log::info('使用call()方法实现定时任务');
})->everyMinute();
}
...
}
command() 实现:
在命令行工具中执行生成 Command 的命令:
$ php artisan make:command RecordLog
实行完成后会在 app/Console/Commands/ 目录下生成 RecordLog.php 文件,打开该文件:
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
class RecordLog extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'command:name';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Command description';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
//
}
}
接下来修改该文件:
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;
class RecordLog extends Command
{
//定义command的名称
protected $signature = 'log:record';
//定义command描述信息(非必须)
protected $description = '定时记录日志';
public function __construct()
{
parent::__construct();
}
//编写相关业务逻辑代码
public function handle()
{
//记录信息到log
Log::info('使用command()方法实现定时任务');
}
}
修改完成后打开 app/Console/Kernel.php 文件,注册 Command:
<?php
namespace App\Console;
use App\Console\Commands\RecordLog;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
use Illuminate\Support\Facades\Log;
class Kernel extends ConsoleKernel
{
//在commands属性中注册对应的command类
protected $commands = [
RecordLog::class,
];
protected function schedule(Schedule $schedule)
{
$schedule->call(function () {
Log::info('使用call()方法实现定时任务');
})->everyMinute();
//执行对应的command,command()方法中填入,command类中 $signature 属性的值
$schedule->command('log:record')->everyMinute();
}
protected function commands()
{
$this->load(__DIR__.'/Commands');
require base_path('routes/console.php');
}
}
修改完成后,在命令行中执行 artisan
命令运行定时任务:
$ php artisan schedule:run
打开日志:
[2019-01-09 16:37:26] local.INFO: 使用call()方法实现定时任务
[2019-01-09 16:37:27] local.INFO: 使用command()方法实现定时任务
信息已记录到日志中,但是现在并不能每分钟都执行,需要结合 Crontab 执行定时任务;
在项目根目录新建一个文本文件,例如 taskSchedule.txt ,写入以下内容:
//每分钟执行 php artisan schedule:run 命令
* * * * * php /path-to-your-project/artisan schedule:run >> /dev/null 2>&1
注意需要把 path-to-your-project 修改为你自己项目的根目录(绝对路径),然后将该文件调价到 Crontab 中:
$ crontab taskSchedule.txt
接下来执行 Crontab:
$ crontab -l
* * * * * php /www/wxapp/artisan schedule:run >> /dev/null 2>&1
等待几分钟查看 Log 是否有信息每分钟定时输出
[2019-01-09 16:50:02] local.INFO: 使用call()方法实现定时任务
[2019-01-09 16:50:03] local.INFO: 使用command()方法实现定时任务
[2019-01-09 16:51:02] local.INFO: 使用call()方法实现定时任务
[2019-01-09 16:51:04] local.INFO: 使用command()方法实现定时任务
大功告成!
注意:每次启动 Crontab 时先将 Crontab 进行移除
//停止定时任务
$ crontab -r
更多使用信息,查询 Laravel 的文档和 Crontab 的资料!
文章同步发布在我的个人博客中,传送门Hesunfly Blog
网友评论