Laravel入坑指南(番外)——任务调度

Laravel提供了很是强劲的命令行工具(若是还不了解,传送到第8往篇),咱们若是想要按期执行某个命令行,能够利用crontab进行定时设置。若是有多个按期的任务,很简单,咱们设定多条crontab规则在不一样时间段内调度不一样的命令便可。php

而Laravel框架内部也提供了这样的调度机制。(固然,仍是逃不过crontab的支持)html

 

首先,咱们须要在crontab中添加这么一条规则node

* * * * * php /path-to-your-project/artisan schedule:run >> /dev/null 2>&1

 

 

其次,全部的调度任务都在/app/Console/Kernel.php的schedule函数中进行调度设置redis

 

 

这个函数中能够调度闭包、可调用对象(包含__invoke的对象)、artisian命令、列队任务以及shell命令。如下以例子进行说明:shell

//调度闭包,->daily()即调度选项,天天凌晨零点运行任务
//关于调度选项后面会统一说明
$schedule->call(function () {
    DB::table('recent_users')->delete();
})->daily();


//调度可调用对象
//DeleteRecentUsers类中包含了__invoke魔术方法
$schedule->call(new DeleteRecentUsers)->daily();


//调度artisian命令
$schedule->command('emails:send --force')->daily();
$schedule->command(EmailsCommand::class, ['--force'])->daily();


//调度列队任务
$schedule->job(new Heartbeat)->everyFiveMinutes();
$schedule->job(new Heartbeat, 'heartbeats')->everyFiveMinutes();    //将job投递到heartbeats列队中


//调度shell命令
$schedule->exec('node /home/forge/script.js')->daily();

经常使用的调度选项:编程

方法 描述
->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(); 只在工做日运行任务
->weekends(); 只在周末运行任务
->sundays(); 每一个星期天运行任务
->mondays(); 每一个星期一运行任务
->tuesdays(); 每一个星期二运行任务
->wednesdays(); 每一个星期三运行任务
->thursdays(); 每一个星期四运行任务
->fridays(); 每一个星期五运行任务
->saturdays(); 每一个星期六运行任务
->between($start, $end); 基于特定时间段运行任务
->when(Closure); 基于特定测试运行任务
->environments($env); 只在指定环境运行任务

 

举几个例子:app

// 每周星期一13:00运行一次...
$schedule->call(function () {
    
})->weekly()->mondays()->at('13:00');


// 工做日的上午8点到下午5点每小时运行...
$schedule->command('foo')
         ->weekdays()
         ->hourly()
         ->timezone('America/Chicago')
         ->between('8:00', '17:00');


//天天7点到22点之间,每小时运行
$schedule->command('reminders:send')
         ->hourly()
         ->between('7:00', '22:00');


//天天23点到4点以外的时间内,每小时运行
$schedule->command('reminders:send')
         ->hourly()
         ->unlessBetween('23:00', '4:00');


//when的闭包返回true时运行
$schedule->command('emails:send')->daily()->when(function () {
    return true;
});


//skip的闭包返回false时运行
$schedule->command('emails:send')->daily()->skip(function () {
    return true;
});

 

 

第三,任务调度的重叠处理框架

当下一次任务开始执行时,万一上一次的任务尚未执行完成,新的任务是会执行的。也就是说,有可能出现屡次任务重叠执行的状况。less

为了不这种状况,咱们可使用外部的手段来加锁,好比文件锁flock,或者redis的setnx均可以。可是Laravel很是贴心,已经帮咱们准备了这样的机制:

$schedule->command('emails:send')->withoutOverlapping();    //锁默认24小时失效

$schedule->command('emails:send')->withoutOverlapping(10);    //锁10分钟失效

 

 

第四,任务调度的顺序

默认状况下,同时调度的多个命令会顺序执行。若是你有一些长时间运行的命令,将会致使随后的命令在预期以后好久才能执行。若是你想要让命令在后台执行以便它们能够同时运,可使用 runInBackground 方法来实现:

$schedule->command('analytics:report')
     ->daily()
     ->runInBackground();

 

 

第五,任务输出

咱们能够将任务中的输出重定向覆盖写入或追加写入文件中,便于问题的排查:

//覆盖写入
$schedule->command('emails:send')
     ->daily()
     ->sendOutputTo($filePath);

//追加写入
$schedule->command('emails:send')
     ->daily()
     ->appendOutputTo($filePath);

 

 

最后,任务钩子

使用 before 和 after 方法,你能够指定在调度任务完成以前和以后要执行的代码:

$schedule->command('emails:send')
         ->daily()
         ->before(function () {
             // 任务即将开始...
         })
         ->after(function () {
             // 任务已经完成...
         });

 

 

好了,Laravel话题到这里正式结束了。关于Laravel还有一些知识点,若是想要深刻了解的小伙伴就去看官方文档吧。

下周开始,博主会进入另外一个话题。至于要写什么,嗯,还没想好,你们下周再见:)

 

 

---------------------------  我是可爱的分割线  ----------------------------

最后博主借地宣传一下,漳州编程小组招新了,这是一个面向漳州青少年信息学/软件设计的学习小组,有意向的同窗点击连接,联系我吧。

相关文章
相关标签/搜索