larave 一直是国内外备受欢迎的框架,功能强大、结构优雅,其中 artisan 命令 也一直备受青睐。接下来就使用 artisan 结合 centOS 的 crontab 功能来实现其调度任务。
首先进入服务器、编辑 crontab 在终端输入: crontab -e 进入编辑页面。在页面最后输入:
* * * * * php_path web_path/artisan schedule:run >> /dev/null 2>&1
* * * * * 每分钟执行
php_path PHP路径 如果不清楚 可使用: which php 命令获取路径
web_path web项目路径 进入项目根目录 执行:pwd 命令获取路径
crontab 基本用法:
crontab -l 查看当前用户的调度任务
crontab -e 编辑调度任务
crontab -r 删除调度任务
/sbin/service crond start 开启
/sbin/service crond stop 停止
/sbin/service crond restart 重启
/sbin/service crond reload 重新加载
crontab 不会开机自动启动、所以如果需要还要设置开机自启动:
在 /etc/rc.d/rc.local 脚本中加入 /sbin/service crond start 即可
服务器设置完成、接下来在项目中配置
在终端进入项目根目录、执行 php artisan make:command order (这里我是项目需要、就直接命名为: order ),此时在项目的:app/Console 下就会多出: Commands/order.php Commands 目录回在执行命令的时候自动创建、多以不需要提前创建。
接下来看看 order.php 文件里有那些配置是需要我们修改的
我在业务逻辑区 记录了执行的 日志,一会配置完成后可以测试一下是否已配置成功
接下来最后一步、我们需要在 app/Console/Kernel.php 文件中加载我们生成的 order 命令 并设置 调用周期
打开 Kernel.php 进行编辑
use App\Console\Commands\order;
protected $commands = [ order::class ];
protected function schedule(Schedule $schedule){
$schedule->command('order')->everyMinute(); // 没分钟执行一次
}
首先在终端执行 php artisan
这里可以看到我新的 orde 命令及描述(这个中文描述在这里确实有点 不入格调)
现在配置基本完成、来测试一下配置是否成功: 在终端 项目根目录下面 执行: php artisan order
终端没有出现报错信息、再查看一下日志文件,发现了我们刚才在 order.php 的 handle() 方法中记录的日志信息,说明我们的命令配置没有问题。接下来我们把服务器的 crontab 服务启动起来,在终端执行: /sbin/service crond start 再次查看日志文件,可以看到我们的记录每分钟添加一条,说明我们的调度任务已经在每分钟执行了。
如果开启 crontab 服务 发现并没有执行定时器、那我们可以直接在终端执行我们再 crontab 添加的命令、查看结果,即:php_path web_path/artisan schedule:run 可找出失败原因。
根据我们的业务需求、我们还可以给命令加参数,如: 再 order.php 设置命令时 配置为: order {1}{2} -- 根据实际业务情况 设置参数 实用 php artisan order 参数值 即可
为了更方便我们实用、laravel 还为我们准备了一些 调用频率设置以及任务钩子等
方法 描述
->cron('* * * * *'); 在自定义Cron调度上运行任务
->everyMinute(); 每分钟运行一次任务
->everyFiveMinutes(); 每五分钟运行一次任务
->everyTenMinutes(); 每十分钟运行一次任务
->everyFifteenMinutes(); 每十五分钟运行一次任务
->everyThirtyMinutes(); 每三十分钟运行一次任务
->hourly(); 每小时运行一次任务
->hourlyAt(17); 每小时第十七分钟运行一次任务
->daily(); 每天凌晨零点运行任务
->dailyAt('13:00'); 每天13:00运行任务
->twiceDaily(1, 13); 每天1:00 & 13:00运行任务
->weekly(); 每周运行一次任务
->monthly(); 每月运行一次任务
->monthlyOn(4, '15:00'); 每月4号15:00运行一次任务
->quarterly(); 每个季度运行一次
->yearly(); 每年运行一次
->timezone('America/New_York'); 设置时区
->weekdays(); 只在工作日运行任务
->sundays(); 每个星期天运行任务
->mondays(); 每个星期一运行任务
->tuesdays(); 每个星期二运行任务
->wednesdays(); 每个星期三运行任务
->thursdays(); 每个星期四运行任务
->fridays(); 每个星期五运行任务
->saturdays(); 每个星期六运行任务
->between($start, $end); 基于特定时间段运行任务
->when(Closure); 基于特定测试运行任务
between 方法用于限定一天中特定时间段的任务执行: $schedule->command('order')->hourly()->between('7:00', '22:00');
unlessBetween 方法用于排除指定时间段任务的执行:$schedule->command('order')->hourly()->unlessBetween('23:00', '4:00');
when 方法用于限制任务基于给定真理测试的结果执行。换句话说,如果给定闭包返回true,只要没有其它约束条件阻止任务运行,该任务就会执行:$schedule->command('order')->daily()->when(function () { return true; });
skip 方法和 when 相反,如果 skip 方法返回true,调度任务将不会执行:$schedule->command('order')->daily()->skip(function () { return true; });
避免任务重叠:$schedule->command('order')->withoutOverlapping();
还可以指定"without overlapping"锁失效前的分钟数,默认情况下,这个锁会在 24 小时后失效:$schedule->command('order')->withoutOverlapping(10);
当 Laravel 处于维护时,调度任务不会运行,不过,如果你想要在维护模式期间强制运行任务,可以使用 evenInMaintenanceMode 方法:$schedule->command('order')->evenInMaintenanceMode();
Laravel 调度器为处理调度任务输出提供了多个方便的方法。首先,使用sendOutputTo 方法,你可以发送输出到文件以便稍后检查:$schedule->command('order')->daily()->sendOutputTo($filePath); 如果想要追加输出到给定文件,可以使用 appendOutputTo
钩子:$schedule->command('order')->daily()->before(function () {// 任务即将开始...})->after(function () {// 任务已经完成...});
使用 pingBefore 和 thenPing方法,调度器可以在任务完成之前和之后自动 ping 给定的 URL。该方法在通知外部服务时很有用,如在调度任务开始或完成的时候 $schedule->command('order')->daily()->pingBefore($url)->thenPing($url);