过去,你可能需要在服务器上为每一个调度任务去创建 Cron 入口。但是这种方式很快会变得不友好,因为这些任务调度不在源代码中,并且你每次都需要通过 SSH 链接登录到服务器中才能增加 Cron 入口。
Laravel 命令行调度器允许你在 Laravel 中对命令调度进行清晰流畅的定义。且使用这个任务调度器时,你只需要在你的服务器上创建单个 Cron 入口。你的任务调度在 app/Console/Kernel.php 的 schedule 方法中进行定义。
当使用这个调度器时,你只需要把下面的 Cron 入口添加到你的服务器中即可:
* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1
这个 Cron 会每分钟执行一次 Laravel 的命令行调度器。当 schedule:run 命令被执行的时候,Laravel 会根据你的调度执行预定的程序。
你可以在 App\Console\Kernel 类的 schedule 方法中定义所有的调度任务。举个例子:每天午夜调用一个闭包。在闭包中,我们会执行一个数据库查询来清空一张表:
call的参数可以是一个闭包也可以是一个, invokable objects。
Invokable objects 指的是 PHP 中含有 __invoke 方法的类,可以理解为一个实现了__invoke方法接口实例。
本质上call函数定义了【执行一段普通代码】这类的任务。
除了上面普通任务之外,也可以定义shell命令或者artisan命令任务的调度,使用command方法:
$schedule->command('emails:send Taylor --force')->daily();
$schedule->command(EmailsCommand::class, ['Taylor', '--force'])->daily();
使用exec命令定义shell命令调度,如下:
$schedule->exec('node /home/forge/script.js')->daily();
使用job方法来调度队列任务,如下:
$schedule->job(new Heartbeat)->everyFiveMinutes();
// 分发任务到「heartbeats」队列...
$schedule->job(new Heartbeat, 'heartbeats')->everyFiveMinutes();
call()/command()/job()等方法都会返回一个拥有Illuminate\Support\Carbon\ManagesFrequencies特性(trait)的实例。此实例定义了一系列控制任务执行频率的方法,使用这些方法可以在高度语义化的基础之上定义任务执行的评率。这些方法如下:
方法 |
描述 |
->cron('* * * * *'); |
自定义 Cron 计划执行任务 |
->everyMinute(); |
每分钟执行一次任务 |
->everyFiveMinutes(); |
每五分钟执行一次任务 |
->everyTenMinutes(); |
每十分钟执行一次任务 |
->everyFifteenMinutes(); |
每十五分钟执行一次任务 |
->everyThirtyMinutes(); |
每三十分钟执行一次任务 |
->hourly(); |
每小时执行一次任务 |
->hourlyAt(17); |
每小时第 17 分钟执行一次任务 |
->daily(); |
每天 0 点执行一次任务 |
->dailyAt('13:00'); |
每天 13 点执行一次任务 |
->twiceDaily(1, 13); |
每天 1 点及 13 点各执行一次任务 |
->weekly(); |
每周日 0 点执行一次任务 |
->weeklyOn(1, '8:00'); |
每周一的 8 点执行一次任务 |
->monthly(); |
每月第一天 0 点执行一次任务 |
->monthlyOn(4, '15:00'); |
每月 4 号的 15 点 执行一次任务 |
->quarterly(); |
每季度第一天 0 点执行一次任务 |
->yearly(); |
每年第一天 0 点执行一次任务 |
->timezone('America/New_York'); |
设置时区 |
->weekdays(); |
限制任务在工作日执行 |
->weekends(); |
限制任务在周末执行 |
->sundays(); |
限制任务在周日执行 |
->mondays(); |
限制任务在周一执行 |
->tuesdays(); |
限制任务在周二执行 |
->wednesdays(); |
限制任务在周三执行 |
->thursdays(); |
限制任务在周四执行 |
->fridays(); |
限制任务在周五执行 |
->saturdays(); |
限制任务在周六执行 |
->between($start, $end); |
限制任务在 $start 和 $end 区间执行 |
->when(Closure); |
限制任务在闭包返回为真时执行 |
->environments($env); |
限制任务在特定环境中执行 |
这些方法也会返回一个Illuminate\Support\Carbon\ManagesFrequencies特性(trait)的实例,这意味着他们可以像查询构造器一样来进行链式调用,如下:
使用when方法和skip方法可以定义当任务满足指定条件的时候执行或者不执行指定的调度,如下:
//当闭包返回true的时候方可执行调度,反之则不执行
$schedule->command('emails:send')->daily()->when(function () { return true; });
//当闭包返回true的时候不执行调度,反之则执行
$schedule->command('emails:send')->daily()->skip(function () { return true; });
当然when方法在链式调用的时候需要所有的when都返回true方可执行调度。
默认情况下,即使之前的任务实例还在执行,调度内的任务也会执行。为避免这种情况的发生,你可以使用 withoutOverlapping 方法:
$schedule->command('emails:send')->withoutOverlapping();
如有需要,你可以在「without overlapping」锁过期之前,指定它的过期时间。默认情况下,这个锁会在 24 小时后过期。
$schedule->command('emails:send')->withoutOverlapping(10);
默认情况下,计划同时运行的多个命令将会顺序执行。若你有长时间运行的命令,这可能导致后续命令的启动时间比预期的更晚(你会发现执行日志中的时间和定义的时间对不上,比如本来定好0点执行的任务,实际执行的时间可能会是1点)。你可以使用 runInBackground 方法让命令在后台运行,如此,它们便可同时运行了:
$schedule->command('analytics:report') ->daily() ->runInBackground();
但是runInBackground只支持command和exec方法定义的调度,也就是artisan命令或者shell命令调度方可支持。
idea激活码,idea注册码,phpstorm激活码,phpstorm注册码,webstorm注册码,webstorm激活码 请参考 https://www.jetbrains-active.com/article/4.html
热门评论